一、 什么是code split
Webpack
的code split
是一种技术,它能够将代码分割成多个块,从而优化应用程序的性能。这样做可以实现按需加载和并行加载,从而减少初始化时间和请求次数。Code split
在Webpack
中通过使用entry
语法和各种Loader
和插件来实现,可以将代码分割成多个文件,然后在需要时加载它们。它可以适用于任何类型和大小的应用程序,尤其适合大型单页应用和跨页面共享代码的应用程序。
二、code split 打包多入口文件
webpack
的code split
可以通过在webpack.config.js
配置文件中设置entry
和output
来实现。entry
指定入口文件,可以通过设置多个entry
来实现code split
。output
则指定输出文件名和输出目录。
例如,我们可以在webpack.config.js
中设置多个entry
,如下所示:
entry: {
app: './src/app.js',
vendor: ['react', 'react-dom', 'lodash'],
polyfills: './src/polyfills.js'
},
其中,app是我们应用程序的入口,vendor包含了我们使用的第三方库,polyfills包含了需要兼容旧浏览器的代码。
接着,在output中,我们可以使用占位符来设置文件名:
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[chunkhash].js'
}
其中,name指entry的键名,chunkhash表示根据文件内容生成的哈希字符串,可以保证文件名的唯一性。
最终,我们的应用程序会被分成多个小的JavaScript文件,例如:
- app.1a2b3c.js
- vendor.4d5e6f.js
- polyfills.7g8h9i.js
这样可以有效地缩短页面加载时间和提高应用程序的性能。
三、code split 提取公共代码
Webpack
的Code Split
技术可以帮助我们提取公共代码,减少页面的加载时间,提高页面的性能。下面我举一个例子来说明如何使用Webpack
的Code Split
技术提取公共代码。
假设我们有一个应用程序,其中包含两个页面:首页和用户页面。我们想要提取公共代码以减少页面的下载时间。为此,我们可以使用Webpack
的多个入口特性,其中每个入口都是一个单独的JavaScript
文件。
首先,在我们的Webpack
配置文件中,定义两个入口文件,如下所示:
entry: {
home: './src/home.js',
user: './src/user.js'
}
然后,我们可以在每个入口文件中使用Webpack
的动态导入技术来加载共享模块。这里,我们使用import()
函数来导入一个包含公共代码的JavaScript
文件:
// home.js
import(/* webpackChunkName: "common" */ './common.js').then(common => {
console.log(common.foo());
});
// user.js
import(/* webpackChunkName: "common" */ './common.js').then(common => {
console.log(common.bar());
});
在这里,我们使用了webpackChunkName
选项来给加载的公共代码 chunk
命名(这里命名为 common
)。这个命名选项对代码拆分起着重要的作用,因为它使得Webpack
可以创建一个独立的chunk
包,其中包含所有的公共模块。
最后,我们需要在Webpack的配置文件(比如output
选项中)中配置Chunk
文件的输出路径和名称。我们可以使用Webpack
的[name]
变量来指定Chunk
文件的名称,如下所示:
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].js',
...
}
在这里,我们配置了Webpack
的输出路径和文件名,使用[name]
变量来指定Chunk
的名称。这意味着,生成的Chunk
文件分别为home.common.js
和user.common.js
(如果我们在之前的代码中使用了不同的名称,则Chunk
文件的名称也相应发生更改)。
通过这种方式,我们可以在Webpack
中实现Code Split
技术,将公共模块提取出来并将它们放在一个独立的Chunk文件中,从而提高页面性能和用户体验。
四. code split 实现按需加载
Webpack的Code Split技术可以将一个大型的应用程序代码拆分成更小的代码块,以便按需加载。这样可以提高应用程序的性能和用户体验,因为只有在需要时才会加载所需的代码。以下是实现按需加载的步骤:
- 定义入口文件和输出文件
在webpack配置文件中,需要定义应用程序的入口文件和输出文件。例如,定义入口文件为app.js,输出文件为bundle.js。
entry: {
app: './app.js'
},
output: {
filename: 'bundle.js'
}
- 使用webpack的splitChunks配置项
使用webpack的splitChunks配置项来将应用程序代码拆分成更小的代码块。可以根据模块的大小、共享依赖项或按需加载等条件来进行拆分。例如,使用以下配置将共享依赖项打包到一个名为vendors的代码块中。
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
- 在应用程序中按需加载代码
可以使用webpack的动态import语法来按需加载代码块。例如,以下代码将异步加载名为lazyModule的代码块。
import('./lazyModule')
.then(module => {
// 模块加载完成后的操作
})
.catch(error => {
// 模块加载失败的处理
});
举例说明:
假设我们有一个应用程序,其中包含三个页面,每个页面都有自己的代码。我们可以将代码拆分成三个代码块,以便按需加载。每个页面的代码可以使用动态import语法按需加载。
entry: {
home: './home.js',
about: './about.js',
contact: './contact.js'
},
output: {
filename: '[name].bundle.js',
path: __dirname + '/dist'
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
现在,在我们的应用程序中,可以使用动态import语法来按需加载每个页面的代码。
// 加载home页面代码
import('./home')
.then(module => {
// 模块加载完成后的操作
})
.catch(error => {
// 模块加载失败的处理
});
// 加载about页面代码
import('./about')
.then(module => {
// 模块加载完成后的操作
})
.catch(error => {
// 模块加载失败的处理
});
// 加载contact页面代码
import('./contact')
.then(module => {
// 模块加载完成后的操作
})
.catch(error => {
// 模块加载失败的处理
});
通过按需加载,我们可以提高页面加载速度和用户体验。只有在需要时才会加载代码,这可以减少初始加载时间和带宽消耗。
五、按需加载eslint校验报错解决方案
如图:
在编译时,eslint会校验import语法
解决方案1:
- 下载
npm i eslint-plugin-import -D
- 配置.eslintrc.js
plugins: [“import”]
- eslintrc.js
module.exports = {
// 继承 Eslint 规则
extends: ["eslint:recommended"],
env: {
node: true, // 启用node中全局变量
browser: true, // 启用浏览器中全局变量
},
plugins: ["import"], // 解决动态导入import语法报错问题 --> 实际使用eslint-plugin-import的规则解决的
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
rules: {
"no-var": 2, // 不能使用 var 定义变量
},
};
解决方案2:
可以在package.json文件中加上如下配置
- package.json
"eslintConfig": {
"parser": "babel-eslint",// 解析器,默认使用Espree
"parserOptions": {
"sourceType": "module", // 指定来源的类型,"script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)
"allowImportExportEverywhere": true // 不限制eslint对import使用位置
}
},
我后面更改打包文件名时报了个错,在这里记录一下
这个就是webpack版本不匹配导致的,我现在的版本是5.85.1
然后我降到5.72.0就好了