webpack advanced usage you get to it?

How to eliminate dead code; js packed his private library; implementation code segmentation and dynamic import enhance the initial loading speed; configuration eslint specification team code standards; packaged abnormal arrest you get to it?

Shake the tree optimization: Tree Shaking

Stone Novel https://www.10tou.com

webpack draws rollup build tool, from 2.0 to achieve support tree shaking, which, after webpack4.0 by opening mode: 'production' that is turned on by default.

tree shaking principle

DCE (Dead code elimination), that is, dead code elimination, the compiler principles, the dead code elimination (Dead code elimination) is a compiler optimization techniques, its purpose is to remove no effect on the operating results of the program code.

Dead Code which features:

  • The code will not be executed, unreachable

  • The results will not be used in code execution

  • The code will only affect died variable (read-only do not write)

Which, tree shaking is to learn from this principle, the use of the characteristics of the ES6 module:

  • In which the import, exports can only appear as a top-level module statement

  • import module name can only be a string constant

  • import the module name is a constant can not be changed

this feature is the use of tree shaking for ES6, essentially static code analysis module, which module is required to determine the code can use to build process, which modules need not be distinguished. By identifying the need to use code to delete unwanted code uglify stage.

tree shaking concept and use

As the name suggests, tree shaking shook the tree optimization which is similar to shaking a tree, the process will make some dead branches leaves fall.

tree shaking is through, if there is more than one module method, if only one of these methods to use, then there is no reference to some of the code in the process of removing this package in the build process, only the method used to break into bundle in.

By opening mode: 'production' can be. Among them, only supports syntax ES6 the way commonjs (that require way) is not supported.

Scope upgrade: Scope Hoisting

webpack module mechanism

We can understand, webpack packed out is a IIFE (immediately call the function expression is often said that the anonymous closures), which, modules each array is a module initialization function, through to load module webpackrequire way, Back module.exports, and by initiator webpackrequire_ (0) manner.

principle and scope hoisting

In the absence of opening scope hoisting, such a code will construct a large number of closure code.

Because the module dependency, packaged by the webpack converted into self-executing anonymous function, so that, due to the large wrap function closures codes, will cause increase in size (more modules more obvious); function scope created when run code increases , leading to memory overhead becomes large.

Wherein, the concept also draws scope hoisting construction principle and incorporated webpak3.0 rollup time, the principle is the code for all modules in accordance with the scope of the function into an introduction order, and then rename the appropriate variables in order to prevent the variable name conflict . This can be achieved to reduce the function declaration code and memory spending.

In webpack4, also just need mode states adjusted to production that is turned on by default, which should be noted that only supports ES6 syntax , dynamic introduction commonjs is not supported.

The webpack3 you need to configure the plug-in  webpack.optimize.ModuleConcatenationPlugin.

Code division dynamic import and

For some large-scale web applications, packaged into a chunk code is not effective, it will lead to load the file is too large, resulting in slow page loads, poor experience. It is required by the code into a plurality of chunks, when the code is run when it needs to be loaded.

一般通过抽离相同代码到一个共享块或者脚本懒加载使得初始下载的代码更小。
前面我们已经说到通过SplitChunksPlugin来进行通用的代码抽离,而懒加载脚本的方式我们需要条件判断等方式通过ES6的动态import的方式实现。
其中,动态import目前没有原生支持,需要babel转换。安装依赖并配置.babelrc

npm i @babel/plugin-syntax-dynamic-import -D

 

配置.babelrc

 

{
     "plugins": [
        "@babel/plugin-syntax-dynamic-import"
    ]
}

 

通过动态import,点击事件加载脚本,demo:

JavaScript语法规范:ESLint

ESLint 是一个插件化并且可配置的 JavaScript 语法规则和代码风格的检查工具,能够及早的发现代码错误并且帮助保持团队代码风格的统一。

其中比较有名的ESLint规范实践有:eslint-config-airbnb、eslint-config-alloy、eslint-config-ivweb等。

可通过基于eslint:recommend配置对规范进行改进。

eslint规则

规则名称 错误级别 说明
for-direction error for循环的方向要求必须正确
getter-return error getter必须有返回值,并且禁止返回值为undefined,比如return
no-await-in-loop off 允许在循环里面使用await
no-console off 允许在代码里面是有console
array-callback-return error 对于数据相关操作函数比如reduce、map、filter等,callback必须有return
accessor-pairs warn 在字符串里面出现(和)进行警告

更多规则可参考:https://eslint.org/docs/rules/

ESLint落地

具体ESLint落地的实施可以有两个方案,通过CI/CD(持续集成/持续交付)系统集成或者和webpack等构建工具集成

ESLint与CI/CD系统集成

gitlab集成lint的常用做法:

本地开发时可以通过增加precommit钩子实现开发环境的检查。
安装husky并配置package

npm i husky -D

 

"scripts":{
    "precommit":"lint-staged"
},
"lint-staged":{
    "linters":{
        "*.js": ["eslint-fix","git add"]
    }
}

 

webpack与ESLint集成

通过使用eslint-loader,构建时检查JS规范。这种做法比较适合新项目的使用。因为该方案会默认在开发构建时对所有文件进行规范的检查。

安装基于react的eslint的依赖包,eslint-config-alloy

npm install --save-dev eslint babel-eslint eslint-plugin-react eslint-config-alloy

 

npm i eslint-loader -D

 

配置.eslintrc.js parser使用babel-eslint,并继承eslint-config-airbnb

npm i eslint-config-airbnb -D

 

 

// .eslintrc.js
module.exports = {
    "parser": "babel-eslint",
    "extends": [
        'alloy',
        'alloy/react',
    ],
    "rules": {
        "indent": ["error",4]
    },
    "env": { // 当前生效环境
        "browser": true,
        "node": true
    }
}

 

打包组件和基础库

webpack不仅可以用来打包应用,也可以用来打包js库来方便我们的日常开发。

实现大整数加法库的打包demo

1、确定打包需求:

  • 需要打包压缩版和非压缩版本

  • 支持script标签/AMD/CJS/ESM模块引入

2、js库的目录结构

 

.
├── dist   // 打包输出文件夹
|   ├── webpack-larger-number.js    // 未压缩版输出文件
|   └── webpack-larger-number.min.js //压缩版
├── package.json // 依赖包配置说明
├── webpack.config.js  // 打包配置
├── index.js     // 
├── src         // 源码
     └── index.js      

 

3、配置webpack

相对于一般打包应用,我们需要配置output参数实现将库暴露出去,其中,library可以指定库的名称

 

module.exports = {
    output: {
        filename: "[name].js",
        library: "WebpackLargeNumber", // 指定库的全局变量
        libraryExport: "default", 
        libraryTarget: "umd" // 支持库引入的方式,默认以libary指定的变量名
    }
}

 

更多详情参数可参考:https://www.webpackjs.com/configuration/output/#output-library

配置webpack,指定.min文件压缩

 

module.exports  = {
    mode: 'none',
    optimization: {
        minimize: true, // 默认为true,压缩js代码
        minimizer: [
            new TerserPlugin({ // terser-webpack-plugin支持es6语法压缩
                include: /\.min\.js$/
            })
        ]
    }

 

更多optimization可参考:https://webpack.docschina.org/configuration/optimization/
然后设置入口文件,对于开发环境则引入未打包的js库,而生产环境则使用压缩后的库

4、设置package的入口文件并设置对应环境变量引入不同的库。

// package.js
 "main": "index.js",

 

 

// index.js
if (process.env.NODE_ENV == 'production') {
    module.exports = requier('./dist/webpack-large-number.min.js')
} else {
    module.exports = require('./dist/webpack-large-number')
}

 

最后,我们也可通过npm publish发布到npm上(ps:需要npm账号),然后我们就可以通过npm下载依赖包 并且通过默认的导出名WebpackLargeNumber.add('99','2')方式直接使用函数。        

大整数加法demo:https://github.com/PCAaron/blogCode/tree/master/webpack/webpack-large-number

优化构建命令行日志:stats + friendly-errors-webpack-plugin

使用webpack打包的时候,默认会将所有的打包构建信息打印出来,而stats选项则可以很好获取部分需要的bundle信息。

常见的stats值:

Preset Alternative Description
errors-only none 只在发生错误时输出
minimal none 只在发生错误或有新的编译时输出
none false 没有输出
normal true 标准输出
verbose none 全部输出

配置webpack,其中,需要注意的是,对于webpack-dev-server,stats需要放到devServer中。

 

module.exports = { 
    stats: 'errors-only'
}

 

通过设置stats为errors-only,我们可以看到dev和build的日志成功的话也没有一些bundle信息,这是,我们可以借助friendly-errors-webpack-plugin对命令行的日志进行优化。

安装friendly-errors-webpack-plugin并配置。

npm i friendly-errors-webpack-plugin -D

 

配置webpack

 

const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
module.exports = {
    plugins: [
        new FriendlyErrorsWebpackPlugin()
    ]
}

 

构建异常和中断处理

如果打包时候存在一些构建异常和中断,需要捕获并做一些异常提示或者内容上报时候,我们可以通过compiler在每次构建结束后出发done的钩子实现异常的抓捕。

其中,我们需要借助node的process.exit抛出异常,默认情况下, process.exit抛出0表示成功,err为null;而非0则执行失败, 其中err为错误信息,code为对应的状态码。

配置webpack

module.exports = {
    plugins: [
        function () {
            this.hooks.done.tap('done', stats => {
                if (stats.compilation.errors && stats.compilation.errors.length &&
                    process.argv.indexOf('--watch') == -1) {
                    console.log('build err')
                    process.exit(1)
                }
            })
        }
    ]
}

 

webpack系列

导读

  • webpack导读
  • webpack与构建工具发展史

webpack基础篇

  • webpack的基本用法:核心概念
  • webpack的基本用法:常用配置

webpack进阶篇

  • webpack的进阶用法(一)

欢迎star关注更新:https://github.com/PCAaron/PCAaron.github.io

推荐阅读

代码demo:https://github.com/PCAaron/blogCode/tree/master/webpack/webpack-improveMore

Scope Hoisting优化Webpack输出:https://www.imweb.io/topic/5a43064fa192c3b460fce360

发布了0 篇原创文章 · 获赞 1 · 访问量 5171

Guess you like

Origin blog.csdn.net/sinat_34560749/article/details/104061762