使用react lottie的webpack从主捆绑包中排除JSON文件
在我们的web应用程序中,我们有一些JSON文件,每个文件大约10-80k行。这些都包含在我们的主捆绑包中。一个名为react-lottie的动画插件使用了它们 我们的使用react lottie的webpack从主捆绑包中排除JSON文件,json,reactjs,webpack,react-router,Json,Reactjs,Webpack,React Router,在我们的web应用程序中,我们有一些JSON文件,每个文件大约10-80k行。这些都包含在我们的主捆绑包中。一个名为react-lottie的动画插件使用了它们 我们的webpack.config.js module.exports={ 条目:[“/src/index.js”], 模块:{ 规则:[ {test://\(js | jsx)$/,exclude:/node_modules/,使用:[“babel loader”]}, { 测试:/\(jpg | png | gif | ico)$/
webpack.config.js
module.exports={
条目:[“/src/index.js”],
模块:{
规则:[
{test://\(js | jsx)$/,exclude:/node_modules/,使用:[“babel loader”]},
{
测试:/\(jpg | png | gif | ico)$/,
使用:{
加载器:“文件加载器”,
选项:{name:“[path][name].[hash].[ext]”
}
}
]
},
解析:{extensions:[“*”,“.js”,“.jsx”]},
输出:{
路径:uu dirname+“/dist”,
公共路径:“/”,
文件名:“[name].[hash].js”
},
插件:[
新建webpack.HotModuleReplacementPlugin(),
新的HtmlWebpackPlugin({hash:false,模板:“src/index.html”}),
新建DashboardPlugin(),
新的CopyWebpackPlugin([
{
from:“src/components/Assets/BookingBar.js”,
致:“assets/BookingBar.js”
}
]),
新BundleAnalyzerPlugin()
],
开发服务器:{
contentBase:“./dist”,
热:是的,
历史上的倒退:是的,
港口:4000
}
};
预期的行为是什么
应该有一种从主捆绑包中排除.json文件的方法。我尝试了文件加载器、json加载器和const someJson=require(./someJson)
其他有关资料:
网页版本:4.16.1
Node.js版本:10.12.0
操作系统:Mac OS 10.14 Mojave
下面的答案(至少是我是如何解决的)。我无法在没有任何数据的情况下初始化lottie。预期的行为是JSON将被捆绑,因为它可能在运行时同步需要。JSON数据与图像文件不同,图像文件是通过
src
属性等在页面上呈现时由浏览器异步加载的
正如前面提到的注释,您应该使用代码拆分。如果您安装并使用@babel/plugin语法动态导入
插件,则最新版本的Webpack支持
npm安装——保存dev@babel/plugin语法动态导入
然后在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>
}
}
在上面的示例中,
及其对应的代码(包括JSON数据)只有在组件实际在运行时呈现时才会被加载。最终,我接受了下面的答案,但在没有任何JSON数据的情况下无法初始化乐透。我最终做了这样的事:
import React, { PureComponent } from "react"
import Lottie from 'react-lottie'
export default class AnimationAutomatedCommunication extends PureComponent {
constructor(props) {
super(props)
this.state = {
animation: <div />
}
}
async componentDidMount() {
const animation = await import(/* webpackChunkName: "AnimationAutomatedCommunication" */ './JsonData/AnimationAutomatedCommunication.json')
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animation.default
}
this.setState({
animation: <div className={this.props.className}>
<Lottie key="lottie-win-jobs" options={defaultOptions}
isStopped={this.props.isStopped} />
</div>
})
}
render() {
return (
<React.Fragment>
{this.state.animation}
</React.Fragment>
)
}
}
import React,{PureComponent}来自“React”
从“react Lottie”导入Lottie
导出默认类AnimationAutomatedCommunication扩展了PureComponent{
建造师(道具){
超级(道具)
此.state={
动画:
}
}
异步组件didmount(){
const animation=wait import(/*webpackChunkName:“AnimationAutomatedCommunication”*/'./JsonData/AnimationAutomatedCommunication.json')
const defaultOptions={
循环:对,
自动播放:对,
animationData:animation.default
}
这是我的国家({
动画:
})
}
render(){
返回(
{this.state.animation}
)
}
}
尝试阅读关于延迟加载(也称为代码拆分)的内容,因此最终JSON将作为块而不是主捆绑包加载。将JSON从主捆绑包中分离出来。您的答案将是完美的,如果我不必使用某种JSON数据初始化react lottie,我最终会在代码库的其他地方使用它,感谢您的全面回复。@GarrettJMU您只需等待呈现react lottie
组件,直到JSON数据加载完毕。在我发布的第三个代码块中,您可以看到如何动态加载JSON数据,并在数据可用时使用Promise.then()
。
// 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>;
}
}
import React, { PureComponent } from "react"
import Lottie from 'react-lottie'
export default class AnimationAutomatedCommunication extends PureComponent {
constructor(props) {
super(props)
this.state = {
animation: <div />
}
}
async componentDidMount() {
const animation = await import(/* webpackChunkName: "AnimationAutomatedCommunication" */ './JsonData/AnimationAutomatedCommunication.json')
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animation.default
}
this.setState({
animation: <div className={this.props.className}>
<Lottie key="lottie-win-jobs" options={defaultOptions}
isStopped={this.props.isStopped} />
</div>
})
}
render() {
return (
<React.Fragment>
{this.state.animation}
</React.Fragment>
)
}
}