React 可加载 JSON 映射文件,其中包含从多个位置引用的组件
Posted
技术标签:
【中文标题】React 可加载 JSON 映射文件,其中包含从多个位置引用的组件【英文标题】:React Loadable JSON mapping file with components being referenced from multiple locations 【发布时间】:2018-12-15 09:11:04 【问题描述】:我正在使用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>
);
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"
],
当其中一个页面在服务器端渲染期间请求它时,像这样'../components/CarsModule'
导入它时,它会为模块未定义(因为包的键是这个"../../../../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,
],
;
但是,没有创建 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"
],
但是,这不是一个非常合理的解决方案,因为其他组件仍然需要引用该 CarsModule。任何想法我做错了什么?提前致谢!
这是我的react-loadable
和webpack
版本:
"react-loadable": "^5.4.0"
"webpack": "^3.5.6"
这是我的.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
]
]
【问题讨论】:
【参考方案1】:是否将模块解析器别名添加到您的 .babelrc
帮助中?
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
[
"module-resolver",
"root": [
"."
],
"alias":
"components": "./components",
],
"react-loadable/babel"
]
这样每个加载器都可以使用相同的路径字符串。
const CarsModule = Loadable(
loader: () => import(/* webpackChunkName: "CarsModule" */ 'components/CarsModule'),
loading()
return <div>Loading...</div>
);
【讨论】:
以上是关于React 可加载 JSON 映射文件,其中包含从多个位置引用的组件的主要内容,如果未能解决你的问题,请参考以下文章
React 页面无法通过带有相对文件路径的 JSON 加载图像