浅析webpack中mode的取值及不同取值的作用/打包方式及摇树优化(tree

您所在的位置:网站首页 mode是啥 浅析webpack中mode的取值及不同取值的作用/打包方式及摇树优化(tree

浅析webpack中mode的取值及不同取值的作用/打包方式及摇树优化(tree

2024-07-13 07:50| 来源: 网络整理| 查看: 265

  Mode 用来指定当前的构建环境是:production、development、还是none。设置 mode 可以使用 webpack 的内置函数,默认值是 production。

  mode 的内置函数功能如下:

  模式(mode):提供 mode 配置选项,告知 webpack 使用相应模式的内置优化。

  用法:只在配置中提供 mode 选项:

module.exports = { mode: 'production' };

  或者从 CLI 参数中传递:

webpack --mode=production 一、mode取值

1、development:会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。

// webpack.development.config.js module.exports = { + mode: 'development' - plugins: [ - new webpack.NamedModulesPlugin(), - new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), - ] }

2、production:会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin。

// webpack.production.config.js module.exports = { + mode: 'production', - plugins: [ - new UglifyJsPlugin(/* ... */), - new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), - new webpack.optimize.ModuleConcatenationPlugin(), - new webpack.NoEmitOnErrorsPlugin() - ] }

  production模式下会启用UglifyJsPlugin插件(移除未使用的内容和文件压缩)

二、mode取值的区别

  分别用 production 和 development 打包,编译的区别如下:

1、development打包后,一些没有依赖的方法、变量、文件会保留;而 production 则会移除。

2、production 打包后,代码会进行压缩,比 development 的文件小。

三、mode不同值的打包

1、none模式下的模块打包

  在没有任何优化处理的情况下,按照webpack默认的情况下打包出模块,它会将模块打包至数组之中,调用模块的时候,就是直接调用模块在此数组中的一个序号,然后没有进行压缩、混淆之类的优化。

  但是无论是在开发环境development下,还是在正式环境production下,这个代码都是不过关的。对于开发环境,此代码可读性太差,对于正式环境,此代码不够简洁。因此为了减少一次重复操作,webpack4提供的development/production可以很大程度上帮我们做一大部分的事情,我们要做的,就是在这些事的基础上增加功能。

2、development模式下,webpack做了哪些打包工作

  development是告诉程序,我现在是开发状态,也就是打包出来的内容要对开发友好。在此mode下,就做了以下插件的事情,其他什么都没有做,所以这些插件可以省略。

//webpack.config.js module.exports = {   mode:'development',   devtool:'eval',   plugins: [     new webpack.NamedModulesPlugin(),     new webpack.NamedChunksPlugin(),     new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") })   ] }

  我们看看NamedModulesPlugin和NamedChunksPlugin这两个插件都做了啥,原本我们的webpack并不会给打包的模块加上名字,一般都是按照序号来,从0开始,然后加载第几个模块,这个对机器来说无所谓,查找载入很快,但是对于人脑来说就是灾难了,所以这个时候给各个模块加上姓名,便于开发的时候查找。

  没有NamedModulesPlugin,模块就是一个数组,引用也是按照在数组中的顺序引用,新增模块都会导致序号的变化。有了NamedModulesPlugin,模块都拥有了姓名,而且都是独一无二的key,不管新增减少多少模块,模块的key都是固定的。

  除了NamedmodulesPlugin,还有一个NamedChunksPlugin,这个是给配置的每个chunks命名,原本的chunks也是数组,没有名字。NamedChunksPlugin其实就是提供了一个功能,你可以自定义chunks的名字,假如我在不同的包中有相同的chunk名,怎么办?这个时候就要在进行进一步的区分了,我们可以用所有的依赖模块名加上本模块名,因为Chunk.modules已经废弃了,现在用其他的方法来代替chunk.mapModules,然后重命名chunk的名字

new webpack.NameChunksPlugin( (chunk) => { return chunk.mapMudoles( m => { return path.relative(m.context,m.request); }).join('_') })

  总结:development也就给我们省略了命名的过程,但是其他还是要我们自己加的。

3、production

  在正式版本中,所省略的插件们,如下所示,我们会一个个分析

//webpack.config.js module.exports = { mode:'production', plugins: [ new UglifyJsPlugin(/*...*/), new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), new webpack.optimize.ModuleConcatenationPlugin(), new webpack.NoEmitOnErrorsPlugin() ] }

(1)UglifyJsPlugin

  我们第一个需要处理的就是混淆&压缩js了吧,这个时候就要请出UglifyJs了,他在webpack中的名字是:const UglifyJsPlugin = require('uglifyjs-webpack-plugin');这样,就可以使用他了。不过 new UglifyJsPlugin() 这个插件我们可以在 optimize 中配置,效果是一样的,那么我们是不是不用在导入一个新的插件了,这样反而会拖慢webpack的打包速度

optimization: { minimize: true }

  将插件去除,混淆压缩放入optimization,这样webpack速度快的起飞了,只有第一次打包会慢,之后在打包就快了

(2)ModuleConcatenationPlugin

  webpack.optimize.ModuleConcatenationPlugin() 这个插件的作用是什么呢?此插件仅适用于由webpack直接处理的ES6模块,在使用转译器(transpiler)时,你需要禁用对模块的处理(例如Babel中的modules选项)。

(3)NoEmitOnErrorsPlugin

  最后一个插件就是webpack.NoEmitOnErrorsPlugin(),这个就是用于防止程序报错,就算有错误也给我继续编译,很暴力的做法。

四、摇树优化

1、概念

  一个模块可能有多个方法,只要其中的某个方法使用到了,则整个文件都会被打包到bundle中去,tree shaking 就是只把用到的的方法打入 bundle,没用到的方法会在 uglify 阶段被擦除掉。 代码不会被执行,不可到达 代码执行的结果不会被用到 代码只会影响死变量(只写不读)   比如: if (false) {   console.log('这段代码永远不会执行') }

  摇树是一种消除死代码的方法,应用程序的依赖项是树状结构,树的每个节点都代表了一个依赖项,这些依赖项为应用程序提供了不同的功能,通过消除不需要的依赖项来减少树的节点,这个过程叫摇树。只能适用于es6模块的导入,不适用于commonJS的require,因为es6的模块是静态引入。

(1)应用程序采用按需加载的方式导出,没有被引用的模块不会被打包进来,减少包大小,缩小应用的加载时间。

(2)es6的模块是静态分析

(3)webpack自带tree shaking,只需要加些配置

// webpack.config.js optimization: { // 使用tree-shaking usedExports: true, // mode为production时,默认开启 },

2、示例

// print.js:导出了两个函数 export const add = (a, b) => { console.log(a + b); } export const minus = (a, b) => { console.log(a - b); } // index.js:只引用了其中一个函数 import { add } from "./print"; add(1, 2);

  tree-shaking结果:

  mode:development,依然将未引入的函数打包了,只是有一句注释标记未被引用,这样做是为了在开发模式下调试方便,如果把代码删除,程序报错时,位置定位不准。

  mode:production,打包后的代码被压缩,且未被引入的函数没有打包。

参考文章:https://blog.csdn.net/qq_40677590/article/details/106817327



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3