Javascript 动态导入:我遗漏了什么吗?
我有一个React项目,它使用Webpack作为捆绑程序,我将我的捆绑包分为两部分——主代码库Javascript 动态导入:我遗漏了什么吗?,javascript,reactjs,webpack,dynamic-import,Javascript,Reactjs,Webpack,Dynamic Import,我有一个React项目,它使用Webpack作为捆绑程序,我将我的捆绑包分为两部分——主代码库main.js,和供应商捆绑包vendor.js 在构建这些捆绑包之后,main.js最终为45kb,vendor.js为651kb 一个特定的供应商库是225kb,似乎是供应商导入中最严重的违规者 我正在文件顶部的页面组件中导入此库: 从“React”导入React; 从“heavyPackage”导入{ModuleA,ModuleB};//225kb进口 ... 常量页=({setThing})=>
main.js
,和供应商捆绑包vendor.js
在构建这些捆绑包之后,main.js
最终为45kb,vendor.js
为651kb
一个特定的供应商库是225kb,似乎是供应商导入中最严重的违规者
我正在文件顶部的页面组件中导入此库:
从“React”导入React;
从“heavyPackage”导入{ModuleA,ModuleB};//225kb进口
...
常量页=({setThing})=>{
...
};
为了尝试将这个繁重的导入加载到一个单独的包中,我尝试使用动态导入来导入这些模块
在页面
组件中,直到调用特定函数,模块才被实际使用,因此我尝试在该范围内而不是在文件顶部导入模块:
从“React”导入React;
...
常量页=({setThing})=>{
...
const handleSignIn=async()=>{
const scopedPackage=wait import('heavyPackage');
常量{moduleA,moduleB}=scopedPackage;
//此处通常使用模块A和模块B
};
};
出于某种原因,我认为Webpack会智能地接受我在这里尝试做的事情,并将这个沉重的包分离成它自己的块,只有在需要时才下载,但最终的包是相同的——一个是45kb的main.js
,一个是651kb的vendor.js
。我在这里的思路是否正确,可能是我的网页配置已关闭,还是我对动态导入的想法是错误的
编辑我已将网页包配置为使用拆分块
拆分捆绑包。以下是我如何配置此功能的:
优化:{
chunkId:“命名”,
分割块:{
缓存组:{
公地:{
块:“首字母”,
maxInitialRequests:5,
minChunks:2,
minSize:0,
},
供应商:{
块:“首字母”,
是的,
名称:“供应商”,
优先事项:10,
测试:/node_模块/,
},
},
},
},
好的,那你看!你有一个带有splitChunks
属性的网页包配置,你还需要在webpack
的输出
对象旁边添加一个chunkFilename
属性
以CRA生成的一个为例
// The build folder.
path: isEnvProduction ? paths.appBuild : undefined,
// Add /* filename */ comments to generated require()s in the output.
pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// THIS IS THE ONE I TALK ABOUT
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: paths.publicUrlOrPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? info =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/')
: isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
// Prevents conflicts when multiple webpack runtimes (from different apps)
// are used on the same page.
jsonpFunction: `webpackJsonp${appPackageJson.name}`,
// this defaults to 'window', but by setting it to 'this' then
// module chunks which are built will work in web workers as well.
globalObject: 'this',
},
一旦你把它放在你的网页上。下一步是安装一个npmi-D@babel/plugin语法动态导入
,并将其添加到babel.config.js中
module.exports=api=>
...
返回{
预设:[
.....
],
插件:[
....
“@babel/plugin语法动态导入”,
....
]
}
然后最后一件事npm安装react loadable
创建一个名为:containers
的文件夹。把所有的容器都放进去
在index.js内部执行以下操作:
可加载对象有两个属性
export const List=可加载({
加载程序:()=>导入(/*WebPackageChunkName:“列表”*/“/list constainer”),
加载:加载,
});
- 加载器:要动态导入的组件
- loadinh:加载动态组件之前要显示的组件
。。。
从“./../containers”导入{Lists,List,User}”;
...
导出函数App():React.ReactElement{
返回(
侧导航
标题
儿子2
);
}
因此,当您捆绑您的代码时,我们会得到如下结果:
那好吧,看!你有一个带有
splitChunks
属性的网页包配置,你还需要在webpack
的输出
对象旁边添加一个chunkFilename
属性
以CRA生成的一个为例
// The build folder.
path: isEnvProduction ? paths.appBuild : undefined,
// Add /* filename */ comments to generated require()s in the output.
pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// THIS IS THE ONE I TALK ABOUT
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: paths.publicUrlOrPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? info =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/')
: isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
// Prevents conflicts when multiple webpack runtimes (from different apps)
// are used on the same page.
jsonpFunction: `webpackJsonp${appPackageJson.name}`,
// this defaults to 'window', but by setting it to 'this' then
// module chunks which are built will work in web workers as well.
globalObject: 'this',
},
一旦你把它放在你的网页上。下一步是安装一个npmi-D@babel/plugin语法动态导入
,并将其添加到babel.config.js中
module.exports=api=>
...
返回{
预设:[
.....
],
插件:[
....
“@babel/plugin语法动态导入”,
....
]
}
然后最后一件事npm安装react loadable
创建一个名为:containers
的文件夹。把所有的容器都放进去
在index.js内部执行以下操作:
可加载对象有两个属性
export const List=可加载({
加载程序:()=>导入(/*WebPackageChunkName:“列表”*/“/list constainer”),
加载:加载,
});
- 加载器:要动态导入的组件
- loadinh:加载动态组件之前要显示的组件
。。。
从“./../containers”导入{Lists,List,User}”;
...
导出函数App():React.ReactElement{
返回(
侧导航
标题
儿子2
);
}
因此,当您捆绑您的代码时,我们会得到如下结果:
@Ernesto的答案提供了一种代码拆分的方法,通过使用
react loadable
和babel dynamic import
插件howev