Tho*_*mas 7 webpack code-splitting code-splitting-async react-loadable
我正在使用React Loadable对我的组件进行代码拆分,但问题是某些组件是从多个位置引用的.例如,我有这个组件CarsModule,在这样的多个区域中引用:
const CarsModule = Loadable({
loader: () => import(/* webpackChunkName: "CarsModule" */ '../components/CarsModule'),
loading() {
return <div>Loading...</div>
}
});
const CarsModule = Loadable({
loader: () => import(/* webpackChunkName: "CarsModule" */ '../../../../components/CarsModule'),
loading() {
return <div>Loading...</div>
}
});
const CarsModule = Loadable({
loader: () => import(/* webpackChunkName: "CarsModule" */ '../../components/CarsModule'),
loading() {
return <div>Loading...</div>
}
});
const CarsModule = Loadable({
loader: () => import(/* webpackChunkName: "CarsModule" */ '../../../../components/CarsModule'),
loading() {
return <div>Loading...</div>
}
});
Run Code Online (Sandbox Code Playgroud)
最终发生在dist/react-loadable.json文件中的是CarsModule看起来像这样:
"../../../../components/CarsModule": [
{
"id": 822,
"name": "./dist/components/CarsModule/index.js",
"file": "0-78a53ff810acc75b6fde.js",
"publicPath": "http://localhost:3000/dist/0-78a53ff810acc75b6fde.js"
}
],
Run Code Online (Sandbox Code Playgroud)
当其中一个页面在服务器端渲染期间请求它,像这样导入它时'../components/CarsModule',它将被模块未定义(因为bundle的密钥是这个"../../../../components/CarsModule").我用它webpackChunkName来尝试在react-loadable.json文件中命名这些键,但没有运气:(
我的webpack prod文件里面有块散列,看起来像这样:
module.exports = {
devtool: 'source-map',
context: path.resolve(__dirname, '..'),
entry: {
main: [
'babel-polyfill',
'./dist/app/defaultClient.js'
],
},
output: {
path: assetsPath,
filename: '[name]-[chunkhash].js',
chunkFilename: '[name]-[chunkhash].js',
publicPath: STATIC_HOST ? `${STATIC_HOST}/dist/` : `http://localhost:3000/dist/`,
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 2,
localIdentName: '[folder]-[local]',
minimize: true,
},
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require('autoprefixer')()],
},
},
{
loader: 'sass-loader',
options: {
outputStyle: 'expanded',
sourceMap: false,
},
},
],
}),
},
{
test: /\.woff2?(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
},
},
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader',
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml',
},
},
},
{
test: webpackIsomorphicToolsPlugin.regular_expression('images'),
use: {
loader: 'url-loader',
options: {
limit: 10240,
},
},
},
],
},
resolve: {
modules: ['node_modules', 'src'],
extensions: ['.json', '.js', '.jsx'],
},
plugins: [
new CleanPlugin([assetsPath], { root: projectRootPath }),
// css files from the extract-text-plugin loader
new ExtractTextPlugin({
filename: '[name]-[chunkhash].css',
allChunks: true,
}),
new webpack.DefinePlugin({
'process.env': exportedClientAppConfigProperties,
__CLIENT__: true,
__DEVTOOLS__: false,
}),
// ignore dev config
new webpack.IgnorePlugin(/\.\/dev/, /\/config$/),
// optimizations
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
}),
new ReactLoadablePlugin({ filename: `./dist/react-loadable.json` }),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
webpackIsomorphicToolsPlugin,
],
};
Run Code Online (Sandbox Code Playgroud)
但是,没有创建的CarsModule.js文件.如果react-loadable.json要将导入位置用作密钥,如何使用从不同位置导入同一模块的多个组件来解决此问题?
如果我删除了从我的项目中执行不同导入的其他文件,将生成react-loadable.json文件,引用CarsModule,如下所示:
"../components/CarsModule": [
{
"id": 822,
"name": "./dist/components/CarsModule/index.js",
"file": "0-78a53ff810acc75b6fde.js",
"publicPath": "http://localhost:3000/dist/0-78a53ff810acc75b6fde.js"
}
],
Run Code Online (Sandbox Code Playgroud)
但是,这不是一个非常合理的解决方案,因为其他组件仍然需要引用CarsModule.我有什么想法我做错了吗?提前致谢!
以下是我的react-loadable&版本webpack:
"react-loadable": "^5.4.0"
"webpack": "^3.5.6"
Run Code Online (Sandbox Code Playgroud)
这是我的.babelrc档案:
{
"presets": [
["env", {
"targets": {
"node": "current",
"browsers": ["last 2 versions", "safari >= 7"]
}
}],
"stage-0",
"react"
],
"plugins": [
"dynamic-import-webpack",
"react-loadable/babel",
"syntax-async-functions",
"syntax-dynamic-import",
"transform-decorators-legacy",
["module-resolver", {
"root": ["./src/"],
}],
["transform-runtime", {
"helpers": false,
"polyfill": true
}]
]
}
Run Code Online (Sandbox Code Playgroud)
添加模块解析器别名对您有.babelrc帮助吗?
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
[
"module-resolver",
{
"root": [
"."
],
"alias": {
"components": "./components",
}
}
],
"react-loadable/babel"
]
}
Run Code Online (Sandbox Code Playgroud)
这样每个加载器都可以使用相同的路径字符串。
const CarsModule = Loadable({
loader: () => import(/* webpackChunkName: "CarsModule" */ 'components/CarsModule'),
loading() {
return <div>Loading...</div>
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1574 次 |
| 最近记录: |