webpack相关

news/2025/2/11 13:21:50/

webpack.docschina.org_ (2).png

在 webpack < 4 的版本中,通常将 vendor 作为一个单独的入口起点添加到 entry 选项中,以将其编译为一个单独的文件(与 CommonsChunkPlugin 结合使用)。而在 webpack 4 中不鼓励这样做。而是使用 optimization.splitChunks 选项,将 vendor 和 app(应用程序) 模块分开,并为其创建一个单独的文件。不要 为 vendor 或其他不是执行起点创建 entry。

Loader

loader 从右到左(或从下到上)地取值(evaluate)/执行(execute)。

module.exports = {module: {rules: [{test: /.css$/,use: [{ loader: 'style-loader' },{loader: 'css-loader',options: {modules: true,},},{ loader: 'sass-loader' },],},],},
};

Q:sideEffects在webpack打包的时候有什么用?

在Webpack中,sideEffects是一个用于标记模块是否有副作用(side effect)的配置选项。副作用是指模块在导入时对全局状态进行修改或对环境造成其他影响,例如修改文件系统、发起网络请求等。对于没有副作用的模块,Webpack可以利用这个信息进行Tree Shaking(摇树优化),将未被使用的代码从最终的打包文件中删除,以减小打包文件的体积。

sideEffects的值可以是一个布尔值或一个数组。如果值为false,表示该模块没有副作用,可以进行Tree Shaking优化;如果值为true或者数组中包含"*",表示该模块具有副作用,不可进行Tree Shaking优化;如果值为一个数组,数组中包含的字符串表示该模块具有副作用的文件路径或通配符。

例如,如果你的项目中有一个模块app.js,它没有副作用,那么可以在它的代码中添加如下注释:

/*#__PURE__*/ // 声明该模块没有副作用
export function add(x, y) {return x + y;
}

然后在Webpack的配置文件中添加以下配置:

module.exports = {// ...module: {rules: [{test: /.js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}}]},optimization: {usedExports: true},// ...// 声明哪些模块没有副作用sideEffects: ["./src/add.js"]
}

这样,在打包时,Webpack会根据sideEffects的配置信息,将没有副作用的模块进行Tree Shaking优化,提高打包性能和减小打包体积。

Q:css或者less文件可以被tree-shaking吗?

在Webpack中,对于纯CSS或Less文件(即没有包含JavaScript代码),无法进行Tree Shaking优化,因为它们不会产生导出的JavaScript代码。Tree Shaking优化是通过检测导出的JavaScript代码的使用情况来删除未使用的代码,因此只有包含导出的JavaScript代码的模块才能进行Tree Shaking优化。

但是,如果你在Less或CSS中使用了类似于PostCSS、Autoprefixer等预处理器,它们可能会将部分JavaScript代码添加到生成的CSS文件中,例如添加浏览器前缀或者自动转换代码。在这种情况下,生成的CSS文件包含了导出的JavaScript代码,因此可以进行Tree Shaking优化。

要使Webpack可以对包含JavaScript代码的CSS或Less文件进行Tree Shaking优化,可以使用mini-css-extract-plugin插件,将CSS或Less文件单独打包成一个JavaScript模块,然后再进行Tree Shaking优化。

例如,在Webpack配置文件中添加以下配置:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {// ...module: {rules: [{test: /.less$/,use: [MiniCssExtractPlugin.loader,"css-loader","less-loader",{loader: "postcss-loader",options: {plugins: [require("autoprefixer")()]}}]}]},plugins: [new MiniCssExtractPlugin({filename: "[name].css",chunkFilename: "[id].css"})],optimization: {usedExports: true}
}

这样,Webpack会将Less文件单独打包成一个JavaScript模块,然后在Tree Shaking优化时检测它的导出代码是否被使用,以删除未使用的代码。

Q:基于上述的描述,那么未被引用到的less或者css文件也就会被自动删除掉吗?

未被引用的CSS或Less文件并不会自动被Webpack删除,因为它们虽然未被引用,但是它们仍然被包含在Webpack的打包文件中,因此仍然会增加打包文件的体积。

如果需要将未使用的CSS或Less文件从打包文件中删除,可以使用插件或者手动处理。

例如,可以使用purgecss-webpack-plugin插件,在打包后对未使用的CSS文件进行删除。这个插件会分析打包后的HTML和JavaScript代码,检测哪些CSS样式类未被使用,然后将其从CSS文件中删除。

安装purgecss-webpack-plugin

npm install -D purgecss-webpack-plugin

在Webpack配置文件中添加以下配置:

const PurgeCssWebpackPlugin = require('purgecss-webpack-plugin');
const glob = require('glob');module.exports = {// ...plugins: [new PurgeCssWebpackPlugin({paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`,  { nodir: true }),// whitelist patternswhitelistPatterns: [/^a-/, /^is-/, /^has-/, /^router-link-active$/]})]
}

这样,purgecss-webpack-plugin就会在打包后检测未使用的CSS样式类,并将其从CSS文件中删除。

需要注意的是,purgecss-webpack-plugin只能处理在HTML和JavaScript代码中使用的CSS样式类,无法处理在CSS文件中定义但未使用的样式类。因此,在使用该插件前需要仔细检查CSS文件,确保所有的样式类都被使用。

Q:webpack4相比于webpack3,升级了哪些地方?

1.性能优化:Webpack 4具有更好的性能和更快的构建速度。新的版本使用了更好的算法和数据结构,以减少构建时间。此外,Webpack 4还通过将模块ID生成算法从数字更改为基于字符串的算法,实现了更好的缓存和更小的包大小。

2.模块优化:Webpack 4优化了模块系统,允许开发者使用ES6模块,并且默认启用Tree Shaking,可以消除未使用的代码,减少包的大小。

3.Mode选项:Webpack 4新增了mode选项,可以配置为“development”、“production”和“none”三种模式,每种模式都有不同的默认配置和插件,便于开发者进行不同环境的构建和优化。

4.新的插件:Webpack 4提供了许多新的插件和特性,如OptimizeCSSAssetsPlugin、SplitChunksPlugin、NoEmitOnErrorsPlugin等。

5.更好的文档:Webpack 4的文档进行了改进,更加清晰明了,方便开发者使用。

Q:SplitChunksPlugin比CommonsChunkPlugin优点在哪儿?

SplitChunksPlugin是Webpack 4中用于代码分割的新插件,与Webpack 3中的CommonsChunkPlugin相比,SplitChunksPlugin有以下几个优点:

  1. 更好的默认配置:SplitChunksPlugin提供了更好的默认配置,可以更好地适应不同的项目需求,而CommonsChunkPlugin需要手动配置选项。

  2. 更灵活的配置选项:SplitChunksPlugin提供了更灵活的配置选项,可以根据实际需求进行定制化设置,例如可以基于模块的大小、被引用的次数等进行分割。

  3. 更好的性能:SplitChunksPlugin相比CommonsChunkPlugin具有更好的性能,可以更有效地将代码分割为更小的块,并实现更好的缓存机制。

  4. 更好的Tree Shaking特性:SplitChunksPlugin可以更好地支持Tree Shaking特性,可以更有效地消除未使用的代码,从而减少打包的体积。

总的来说,SplitChunksPlugin在功能和性能上都比CommonsChunkPlugin更优秀,可以更好地满足现代前端项目的需求。但是,如果您正在使用Webpack 3,CommonsChunkPlugin仍然是可用的,并且可以实现代码分割的功能。

CommonsChunkPlugin是Webpack中用于提取公共代码的插件,它的作用是将多个入口文件中相同的代码提取到一个单独的文件中,以便在多个页面之间共享使用,避免代码重复和增加页面加载时间。以下是CommonsChunkPlugin的常用配置选项:

  • name:表示提取出的公共模块的名称,可以使用字符串或者函数来指定名称。

  • filename:表示生成的文件名,可以使用[hash]等占位符。

  • minChunks:表示在多少个模块中使用的模块才会被提取为公共模块,默认值是2,也可以使用函数来指定。

  • chunks:表示在哪些入口chunk中使用的模块才会被提取为公共模块,可以是一个字符串或字符串数组,也可以是一个函数。

  • children:表示是否在所有的chunk中查找公共模块,默认值是false。

  • async:表示将异步加载的模块中公共部分提取到单独的文件中。

Q:webpack5相比于webpack4做了哪些升级?

Webpack 5 相比于 Webpack 4 做了很多升级,以下是一些主要的升级点:

  1. 更快的构建速度:Webpack 5 使用了一些新的技术,如持久化缓存和更好的多线程处理,从而提高了构建速度和性能。

  2. 更好的 Tree Shaking:Webpack 5 在 Tree Shaking 算法上进行了优化,可以更准确地识别和剔除没有使用的代码。

  3. 更好的模块解析:Webpack 5 对模块解析进行了升级,支持更多的模块类型和模块路径解析方式,例如支持 type: module,从而使得 ES Modules 能够更好地工作。

  4. 更好的代码块拆分:Webpack 5 对代码块拆分进行了升级,支持动态导入的模块和代码块,可以更好地控制代码块的大小和数量。

  5. 更好的输出管理:Webpack 5 对输出管理进行了升级,支持更多的输出选项和格式,例如支持输出 ESM 格式的代码。

  6. 更好的错误处理:Webpack 5 对错误处理进行了升级,可以提供更详细和有用的错误信息和提示。

  7. 更好的插件系统:Webpack 5 对插件系统进行了升级,支持更多的插件选项和钩子,例如支持 beforeRunafterEmit 两个新的钩子。

  8. 更好的缓存管理:Webpack 5 对缓存管理进行了升级,支持更多的缓存选项和控制方式,例如支持自定义缓存目录和缓存方式。

除了以上几点之外,Webpack 5 还有很多其他的升级和改进,可以去官方文档查看详细信息。总的来说,Webpack 5 对 Webpack 4 进行了全面的升级和改进,提高了构建速度、代码质量和开发体验。

Q:webpack为什么对于Import()的模块会单独创建一个或者多个异步块?

Webpack对import()的模块单独创建异步块的目的是实现代码分割(code splitting)和按需加载(on-demand loading)的优化策略。

代码分割是一种将代码拆分成较小块的技术,它可以使应用程序在加载时只请求所需的代码块,而不是一次性加载所有代码。这样可以减少初始加载时间,并提高应用程序的性能。通过将import()的模块单独创建异步块,Webpack能够将这些模块的代码与主应用程序的代码分离,使得在初始加载时只加载必要的代码,延迟加载其他模块。

异步块的创建还使得按需加载成为可能。当应用程序需要某个模块时,可以通过动态导入(import())该模块来触发异步请求,从而按需加载该模块的代码。这种按需加载的方式可以根据用户操作、路由变化或其他条件来决定何时加载特定模块,以优化应用程序的性能和资源利用。

另外,通过将import()的模块单独创建异步块,Webpack还能够利用浏览器的并行加载能力。当浏览器发起异步请求时,它可以同时请求多个文件,从而加快加载速度。

总之,通过将import()的模块单独创建异步块,Webpack实现了代码分割和按需加载的优化策略,以提高应用程序的性能和加载速度。它允许开发人员根据需要延迟加载模块,减少初始加载的大小,并充分利用浏览器的并行加载能力。

Q:为什么有的模块没有被使用,但是也没有tree-shaking掉?

如果一个模块没有显示的声明sideEffects,也没用添加/#PURE/这样的声明。那么就要依赖Terser来进行推断副作用了。但是在现实场景下,这是一件很困难的事情。贴一下webpack官方文档里的一个demo:

import { Button } from '@shopify/polaris';import hoistStatics from 'hoist-non-react-statics';function Button(_ref) {// ...
}function merge() {var _final = {};for (var _len = arguments.length, objs = new Array(_len), _key = 0;_key < _len;_key++) {objs[_key] = arguments[_key];}for (var _i = 0, _objs = objs; _i < _objs.length; _i++) {var obj = _objs[_i];mergeRecursively(_final, obj);}return _final;
}function withAppProvider() {return function addProvider(WrappedComponent) {var WithProvider =/*#__PURE__*/(function (_React$Component) {// ...return WithProvider;})(Component);WithProvider.contextTypes = WrappedComponent.contextTypes? merge(WrappedComponent.contextTypes, polarisAppProviderContextTypes): polarisAppProviderContextTypes;var FinalComponent = hoistStatics(WithProvider, WrappedComponent);return FinalComponent;};
}var Button$1 = withAppProvider()(Button);export {// ...,Button$1,
};

When Button is unused you can effectively remove the export { Button$1 }; which leaves all the remaining code. So the question is “Does this code have any side effects or can it be safely removed?”. Difficult to say, especially because of this line withAppProvider()(Button). withAppProvider is called and the return value is also called. Are there any side effects when calling merge or hoistStatics? Are there side effects when assigning WithProvider.contextTypes (Setter?) or when reading WrappedComponent.contextTypes (Getter?).

Terser actually tries to figure it out, but it doesn’t know for sure in many cases. This doesn’t mean that terser is not doing its job well because it can’t figure it out. It’s too difficult to determine it reliably in a dynamic language like JavaScript.

reference: https://webpack.js.org/guides/tree-shaking/#clarifying-tree-shaking-and-sideeffects


http://www.ppmy.cn/news/862646.html

相关文章

多元融合:流媒体传输网络的全盘解法

我们在寻找「网络」的全盘解法。 音视频数字化在消费领域的红利俨然见顶&#xff0c;而产业级视频应用激活了更多场景下的业务模式。与此同时&#xff0c;音视频客户也从单一的业务需求&#xff0c;趋向于多种业务并行存在的需求。 固有的网络能满足新兴的业态吗&#xff1f;延…

设置外键

数据的修改&#xff1a; update 数据表名称 set 字段。。。 where 。。。&#xff1b; 通过两个表的关联修改&#xff1a;update goods as g inner join goods_cates as c on g.catenamec.name set g.namec.id 把从一个里查询到的数据插入到另一个表&#xff1a;insert into …

sql server设置外键

首先选择设置外键的表&#xff0c;右键“设计” 然后单击随便选择一个字段&#xff0c;选择“关系” 选择“表和列规范” 在主键表那里选择外键的数据来源表&#xff0c;比如score的外键courseid完全来源于course表的courseid&#xff0c;所以这里选择course表&#xff0c;表选…

mysql设置外键的四种方法(转载)

mysql设置外键的四种方法&#xff08;转载&#xff09;

数据库入门-主键和外键设置

一:)在所想要设置为主键的列上单击右键&#xff0c;点击设置为主键&#xff0c;设置成功后该列上有一个钥匙&#x1f511;图标 二:)设置外键单击右键选择 点击添加 点击设计器 点击表和列规范 后面的框中点一下&#xff0c;就会出现后面的三个点的按钮&#xff0c;点击三个点图…

给表设置外键

先介绍一下基本情况: 现在有两个表一张是t_blog表(博客表)&#xff0c;一张是t_blogType表(博客类别) 现在我想把t_blog表中的typeID属性设置为外键&#xff0c;关联t_blogType表中的id属性。 1,右键t_blog表&#xff0c;设计表&#xff0c;选择外键属性 2&#xff0c;然后会…

如何在MySQL中设置外键约束以及外键的作用

如何在MySQL中设置外键约束以及外键的作用 1.外键的作用,主要有两个: 一个是让数据库自己通过外键来保证数据的完整性和一致性 一个就是能够增加ER图的可读性 2.外键的配置 1)先创建一个主表&#xff0c;代码如下&#xff1a; #创建表student,并添加各种约束 create table stud…

Navicat中的外键设置说明

1.什么是外键&#xff0c;简单可以理解为依赖 定义:外键是指引用另外一个表中的一列或多列数据&#xff0c;被引用的列应该具有主键约束或者唯一性约束。外键用来建立和加强两个表数据之间的连接。 student和grade&#xff0c;学生表中的gid是学生所在的班级id&#xff0c;是…