在故事书中用反应本机矢量图标反应本机网络问题
React native web issue with react native vector icons in storybook
我使用 React Native Web 创建了一个项目,我得到了适用于 Web 和移动设备的 React Native 图标,故事书除外。我不确定如何告诉故事书 webpack 配置来加载 FontAwesome 字体。我尝试在预览中添加 FontAwesome-head.html 但仍然没有显示图标只是一个矩形作为占位符。我想要的是让我的图标显示在故事书 webpack 服务器中。
.storybook/main.js:
const webpack = require('webpack');
const path = require('path');
const rootDir = path.join(__dirname, '..');
module.exports = {
stories: ['../src/storybook/stories/*.stories.tsx'],
// addons: ['@storybook/addon-docs', '@storybook/addon-viewport', '@storybook/addon-knobs/', '@storybook/addon-links/', '@storybook/addon-actions/'],
webpackFinal: async config => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve('awesome-typescript-loader'),
options: {
transpileOnly: true
}
}
],
},
{
test: /\.ttf$/,
loader: 'url-loader', // or directly file-loader
include: path.resolve(
__dirname,
'../node_modules/react-native-vector-icons',
),
},
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules[/\](?!react-native|react-native-vector-icons|react-color|react-native-gesture-handler|@react-native-community|react-navigation|@react-navigation\/.*)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'module:metro-react-native-babel-preset',
'@babel/preset-env',
'@babel/preset-flow',
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
'react-native-web',
],
},
},
},
)
config.plugins.push(
new webpack.DefinePlugin({
__DEV__: process.env.NODE_ENV !== 'production',
}),
);
config.resolve.alias = {
...(config.resolve.alias || {}),
'react-native': 'react-native-web',
'@storybook/react-native': '@storybook/react',
'@sentry/react-native': '@sentry/react',
'react-native-maps': 'react-native-web-maps',
'react-native-gesture-handler/GestureHandler': require.resolve(
'react-native-gesture-handler/GestureHandler',
),
'react-native-gesture-handler/RNGestureHandlerModule': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler/RNGestureHandlerModule.web.js',
),
'./RNGestureHandlerModule': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler/RNGestureHandlerModule.web.js',
),
'./GestureHandlerButton': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler',
'GestureHandlerButton.web.js',
),
'./GestureComponents': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler',
'GestureComponents.web.js',
),
'./PlatformConstants': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler',
'PlatformConstants.web.js',
),
'@utilities': path.resolve(__dirname, '../src/utilities/'),
'@queries': path.resolve(__dirname, '../src/queries'),
'@pages': path.resolve(__dirname, '../src/components/pages'),
'@styled-components': path.resolve(
__dirname,
'../src/types/libraries/styled-components.ts',
),
'@hooks': path.resolve(__dirname, '../src/hooks'),
'@atoms': path.resolve(__dirname, '../src/components/atoms'),
'@molecules': path.resolve(__dirname, '../src/components/molecules'),
'@resources': path.join(__dirname, '../src/resources'),
'@providers': path.resolve(__dirname, '../src/providers'),
'@enums': path.resolve(__dirname, '../src/enums'),
'@common': path.resolve(__dirname, '../src/components/common'),
'@contexts': path.resolve(__dirname, '../src/contexts'),
'@util': path.resolve(__dirname, '../src/components/util'),
'@images': path.resolve(__dirname, '../src/assets/images'),
'@icons': path.resolve(__dirname, '../src/assets/icons'),
'@fonts': path.resolve(__dirname, '../src/assets/fonts'),
};
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules[0].use[0].options.plugins.push(['react-native-web', { commonjs: true }]);
return config;
},
};
.storybook/preview-head.html
<link href="https://fonts.googleapis.com/css?family=Quicksand:400,700" rel="stylesheet">
<style type="text/css">
@font-face {
font-family: Quicksand-Bold;
src: url('https://fonts.gstatic.com/s/a/6bb475d143c61221c4ea174d3c51728268e58b12dbc14600d59020ef8deaaead.ttf');
}
@font-face {
font-family: Quicksand-Regular;
src: url('https://fonts.gstatic.com/s/a/0f408f35c3679417b5580701f3ac08830ce36535af5a643a2ef5b59e91c3c6b7.ttf');
}
@font-face {
font-family: Lato-Regular;
src: url('https://fonts.gstatic.com/s/a/a649aaf21573a59079c46db19314fd95648f531e610fa932101f2705616b2882.ttf');
}
@font-face {
font-family: Lato-Bold;
src: url('https://fonts.gstatic.com/s/a/407592da08cb1f6060fbc69262ad33edd0b61ec9160521455eca8f726bbd4353.ttf');
}
</style>
<script>
import FontAwesome from '../node_modules/react-native-vector-icons/FontAwesome.js';
// Generate required css
import {iconFont} from '../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf';
const iconFontStyles = `@font-face {
src: url(${iconFont});
font-family: FontAwesome;
}`;
// Create stylesheet
const style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = iconFontStyles;
} else {
style.appendChild(document.createTextNode(iconFontStyles));
}
// Inject stylesheet
document.head.appendChild(style);
try {
FontAwesome.loadFont();
console.log("working!");
} catch (e) {
console.log(e);
}
</script>
package.json
"storybook:web": "start-storybook -p 6006"
我认为问题存在于 preview-head.html 中,我知道我不能在脚本标签中使用导入模块,但不确定还有什么地方可以加载 fontAwesome 以便 storybook 可以选择它。谢谢!
对于遇到此问题的任何人,我需要具体说明要为 url 加载程序包含哪个文件。
此更改修复了错误:
{
test: /\.ttf$/,
loader: 'url-loader', // or directly file-loader
include: path.resolve(
__dirname,
'../node_modules/react-native-vector-icons/FontAwesome5.js',
),
},
我也将 font awesome 脚本移到了 preview.js 文件中
我使用 React Native Web 创建了一个项目,我得到了适用于 Web 和移动设备的 React Native 图标,故事书除外。我不确定如何告诉故事书 webpack 配置来加载 FontAwesome 字体。我尝试在预览中添加 FontAwesome-head.html 但仍然没有显示图标只是一个矩形作为占位符。我想要的是让我的图标显示在故事书 webpack 服务器中。
.storybook/main.js:
const webpack = require('webpack');
const path = require('path');
const rootDir = path.join(__dirname, '..');
module.exports = {
stories: ['../src/storybook/stories/*.stories.tsx'],
// addons: ['@storybook/addon-docs', '@storybook/addon-viewport', '@storybook/addon-knobs/', '@storybook/addon-links/', '@storybook/addon-actions/'],
webpackFinal: async config => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve('awesome-typescript-loader'),
options: {
transpileOnly: true
}
}
],
},
{
test: /\.ttf$/,
loader: 'url-loader', // or directly file-loader
include: path.resolve(
__dirname,
'../node_modules/react-native-vector-icons',
),
},
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules[/\](?!react-native|react-native-vector-icons|react-color|react-native-gesture-handler|@react-native-community|react-navigation|@react-navigation\/.*)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'module:metro-react-native-babel-preset',
'@babel/preset-env',
'@babel/preset-flow',
'@babel/preset-typescript',
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
'react-native-web',
],
},
},
},
)
config.plugins.push(
new webpack.DefinePlugin({
__DEV__: process.env.NODE_ENV !== 'production',
}),
);
config.resolve.alias = {
...(config.resolve.alias || {}),
'react-native': 'react-native-web',
'@storybook/react-native': '@storybook/react',
'@sentry/react-native': '@sentry/react',
'react-native-maps': 'react-native-web-maps',
'react-native-gesture-handler/GestureHandler': require.resolve(
'react-native-gesture-handler/GestureHandler',
),
'react-native-gesture-handler/RNGestureHandlerModule': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler/RNGestureHandlerModule.web.js',
),
'./RNGestureHandlerModule': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler/RNGestureHandlerModule.web.js',
),
'./GestureHandlerButton': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler',
'GestureHandlerButton.web.js',
),
'./GestureComponents': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler',
'GestureComponents.web.js',
),
'./PlatformConstants': path.join(
rootDir,
'node_modules',
'react-native-gesture-handler',
'PlatformConstants.web.js',
),
'@utilities': path.resolve(__dirname, '../src/utilities/'),
'@queries': path.resolve(__dirname, '../src/queries'),
'@pages': path.resolve(__dirname, '../src/components/pages'),
'@styled-components': path.resolve(
__dirname,
'../src/types/libraries/styled-components.ts',
),
'@hooks': path.resolve(__dirname, '../src/hooks'),
'@atoms': path.resolve(__dirname, '../src/components/atoms'),
'@molecules': path.resolve(__dirname, '../src/components/molecules'),
'@resources': path.join(__dirname, '../src/resources'),
'@providers': path.resolve(__dirname, '../src/providers'),
'@enums': path.resolve(__dirname, '../src/enums'),
'@common': path.resolve(__dirname, '../src/components/common'),
'@contexts': path.resolve(__dirname, '../src/contexts'),
'@util': path.resolve(__dirname, '../src/components/util'),
'@images': path.resolve(__dirname, '../src/assets/images'),
'@icons': path.resolve(__dirname, '../src/assets/icons'),
'@fonts': path.resolve(__dirname, '../src/assets/fonts'),
};
config.resolve.extensions.push('.ts', '.tsx');
config.module.rules[0].use[0].options.plugins.push(['react-native-web', { commonjs: true }]);
return config;
},
};
.storybook/preview-head.html
<link href="https://fonts.googleapis.com/css?family=Quicksand:400,700" rel="stylesheet">
<style type="text/css">
@font-face {
font-family: Quicksand-Bold;
src: url('https://fonts.gstatic.com/s/a/6bb475d143c61221c4ea174d3c51728268e58b12dbc14600d59020ef8deaaead.ttf');
}
@font-face {
font-family: Quicksand-Regular;
src: url('https://fonts.gstatic.com/s/a/0f408f35c3679417b5580701f3ac08830ce36535af5a643a2ef5b59e91c3c6b7.ttf');
}
@font-face {
font-family: Lato-Regular;
src: url('https://fonts.gstatic.com/s/a/a649aaf21573a59079c46db19314fd95648f531e610fa932101f2705616b2882.ttf');
}
@font-face {
font-family: Lato-Bold;
src: url('https://fonts.gstatic.com/s/a/407592da08cb1f6060fbc69262ad33edd0b61ec9160521455eca8f726bbd4353.ttf');
}
</style>
<script>
import FontAwesome from '../node_modules/react-native-vector-icons/FontAwesome.js';
// Generate required css
import {iconFont} from '../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf';
const iconFontStyles = `@font-face {
src: url(${iconFont});
font-family: FontAwesome;
}`;
// Create stylesheet
const style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = iconFontStyles;
} else {
style.appendChild(document.createTextNode(iconFontStyles));
}
// Inject stylesheet
document.head.appendChild(style);
try {
FontAwesome.loadFont();
console.log("working!");
} catch (e) {
console.log(e);
}
</script>
package.json
"storybook:web": "start-storybook -p 6006"
我认为问题存在于 preview-head.html 中,我知道我不能在脚本标签中使用导入模块,但不确定还有什么地方可以加载 fontAwesome 以便 storybook 可以选择它。谢谢!
对于遇到此问题的任何人,我需要具体说明要为 url 加载程序包含哪个文件。
此更改修复了错误:
{
test: /\.ttf$/,
loader: 'url-loader', // or directly file-loader
include: path.resolve(
__dirname,
'../node_modules/react-native-vector-icons/FontAwesome5.js',
),
},
我也将 font awesome 脚本移到了 preview.js 文件中