在我们的网络应用中,我们有一些JSON文件,每个文件的行数约为10-80k。这些已包含在我们的主捆绑包中。这些由名为react-lottie的动画插件使用。
我们的webpack.config.js
的示例
module.exports = {
entry: ["./src/index.js"],
module: {
rules: [
{ test: /\.(js|jsx)$/, exclude: /node_modules/, use: ["babel-loader"] },
{
test: /\.(jpg|png|gif|ico)$/,
use: {
loader: "file-loader",
options: { name: "[path][name].[hash].[ext]" }
}
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: __dirname + "/dist",
publicPath: "/",
filename: "[name].[hash].js"
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({ hash: false, template: "src/index.html" }),
new DashboardPlugin(),
new CopyWebpackPlugin([
{
from: "src/components/Assets/BookingBar.js",
to: "assets/BookingBar.js"
}
]),
new BundleAnalyzerPlugin()
],
devServer: {
contentBase: "./dist",
hot: true,
historyApiFallback: true,
port: 4000
}
};
预期的行为是什么?
应该有一种从主捆绑包中排除.json文件的方法。我已经尝试了File-Loader,json-loader和const someJson = require(./ someJson)
其他相关信息:
Webpack版本:4.16.1
Node.js版本:10.12.0
操作系统:Mac OS 10.14 Mojave
下面的答案(我如何解决)。我无法在没有任何数据的情况下初始化彩票。
最佳答案
预期的行为是JSON将被捆绑,因为大概在运行时需要同步。 JSON数据不同于图像文件之类的东西,图像文件是由浏览器异步加载的,因为它们是通过src
属性等呈现在页面上的。
如前所述,您应该使用代码拆分。如果您安装并使用@babel/plugin-syntax-dynamic-import
插件,则最新版本的Webpack支持dynamic imports。npm install --save-dev @babel/plugin-syntax-dynamic-import
然后在babel.config.js
中:
module.exports = {
...
plugins: [
"@babel/plugin-syntax-dynamic-import"
]
...
};
示例
假设您有一个React组件,它可能需要一些JSON数据,但不需要作为捆绑包的一部分同步加载。您的非代码拆分版本可能如下所示:
import React from 'react';
import myJSON from './myJSON.json';
export default class MyComponent extends React.Component {
render() {
return <div>{JSON.stringify(myJSON, null, 2)}</div>
}
}
相反,您可以使用动态导入-基本上是运行时导入,它返回一个Promise,您可以使用该异步加载与包分开的分块数据:
import React from 'react';
import myJSON from './myJSON.json';
export default class MyComponent extends React.Component {
state = {data: {}};
componentDidMount() {
import(/* webpackChunkName: 'myJSON' */ './myJSON.json')
.then((data) => {
this.setState({data});
});
}
render() {
return <div>{JSON.stringify(this.state.data, null, 2)}</div>
}
}
或者,您可以将React的新
lazy
和Suspense
API(v16.6.0及更高版本)用于dynamically import React components,这些API与捆绑包分开进行分块。如果您想将组件及其对应的JSON数据分块在一起,但又与主捆绑包分开,则可能更可取:// MyComponent.jsx
import React from 'react';
import myJSON from './myJSON.json';
export default class MyComponent extends React.Component {
render() {
return <div>{JSON.stringify(myJSON, null, 2)}</div>
}
}
// SomeParent.jsx
import React, {lazy, Suspense} from 'react';
const MyComponent = lazy(() => import(/* webpackChunkName: 'MyComponent' */ './MyComponent'));
export default class SomeParent extends React.Component {
render() {
return <div>
<Suspense fallback={<div>Loading...<div>} >
<MyComponent />
</Suspense>
</div>;
}
}
在上面的示例中,
<MyComponent />
及其相应的代码(包括JSON数据)仅在组件在运行时实际呈现时才加载。