让前端飞Web前端之路前端开发那些事

30分钟快速过一遍Webpack4核心知识

2019-05-26  本文已影响0人  JokerPeng

1、webpack和webpack-dev-server区别

webpack 每次会生成一个bundle.js文件,webpack-dev-server不会,只是将打包结果放在内存中,并不会写入实际的bundle.js,在每次webpack-dev-server接收到请求时,都将内存中的打包结果返回给浏览器。

2、webpack-cli安装后可以直接在控制台调用webpack命令

3、url-loader 和 file-loader

url-loaderfile-loader都可以用来作为打包图片的loader

4、style-loader作用主要是将css放到dom中

官方英文解释很到位:Adds CSS to the DOM by injecting a <style> tag

如果配置style-loader/url,则会生成一个类似<link rel="stylesheet" href="path/to/file.css">这样的内联css。

5、postcss-loader与Autoprefixer一起,用来适配各大浏览器厂商css前缀

6、模块样化处理

{
  loader: 'css-loader',
  options: {
    importLoaders: 2,
    modules: true,
  },
},

如上在配置css-loader时候,配置modules: true

但一般出路antd的样式时候,需要做两手处理:

{
    test: /\.less$/,
    include: /node_modules\/antd/,
    use: [
        'style-loader',
        { loader: 'css-loader', options: {modules: false} },
        'less-loader'
    ]
},
{
    test: /\.less$/,
    exclude: /node_modules\/antd/,
    use: [
        'style-loader',
        { loader: 'css-loader', options: {modules: true} },
        'less-loader'
    ]
}

这样避免了 css-modules 对 antd 的样式进行处理,否则会造成antd 的样式的不匹配。

7、iconfont字体打包

{
    test: /\.(eot|ttf|svg|woff)$/,
     use: {
        loader: 'file-loader',
    },
}

如上示例,打包.eot, .ttf等字体文件

8、html-webpack-plugin

9、clean-webpack-plugin

10、output.publicPath

11、source-map

12、devServer

13、hot-module-replacement

14、配置Babel

npm install --save-dev babel-loader @babel/core

webpack 设置:

module: {
  rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
    }
  ]
}

.babelrc 文件设置如下:

npm install @babel/preset-env --save-dev

{
    "presets": ["@babel/preset-env"]
}

但面对更低版本的浏览器的时候,像promise还需要转化注入,就需要引入babel/polyfill

在对应业务js代码文件开头引入polyfill import "@babel/polyfill";

但是这样有个缺点,就是会把所有es6转es5的需要的语法都给打包到对应文件,造成打包文件过大。

如果需要按需去打包polyfill语法,根据代码需要,可以设置文件 .babelrc

{
    "presets": [["@babel/preset-env", {
    "targets": {
        chrome: "67"
    },
    "useBuiltIns": "usage",
    }]],
}

上面配置中的 targets 中配置的浏览器版本,是指大于该版本的浏览器,根据该浏览器对es6的支持情况去有针对性的打包polyfill代码,这样可以让打包文件变得更小一点,比如如果chrome67以上的版本浏览器对promise支持很好,那么就不需要打包promise的语法了,更不需要对promise去转码。

总的来说,polyfill修改了全局作用域,浏览器下是window,node下是global。

babel-polyfill主要由两部分组成,core-js和regenerator runtime。

core-js:提供了如ES5、ES6、ES7等规范中 中新定义的各种对象、方法的模拟实现。
regenerator:提供generator支持,如果应用代码中用到generator、async函数的话用到。

引入babel-polyfill全量包后文件会变得非常大。

npm install --save-dev @babel/plugin-transform-runtime

npm install --save @babel/runtime @babel/runtime-corejs2

删除对应文件开头的引入 import "@babel/polyfill";

.babelrc 文件设置如下:

{
    "plugins": [["@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false,
      }]],
}

@babel/plugin-transform-runtime 会以闭包的形式

15、Tree Shaking

// outer.js

export const foo = () => {
  console.log('Fucked Up');
};

export const bar = () => {
  console.log('Beyond All Repair');
};

// index.js
import { foo } from './outer';

foo();

然后配置webpack.config.js文件,添加如下modeoptimization2个配置:

// webpack.config.js
mode: 'development',
optimization: {
    usedExports: true,
},

然后打包,打开打包好的文件,可以看到如下部分:

/***/ "./src/outer.js":
/*!**********************!*\
  !*** ./src/outer.js ***!
  \**********************/
/*! exports provided: foo, bar */
/*! exports used: foo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return foo; });\n/* unused harmony export bar */\nvar foo = function foo() {\n  console.log('Fucked Up');\n};\nvar bar = function bar() {\n  console.log('Beyond All Repair');\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvb3V0ZXIuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvb3V0ZXIuanM/NGJlZiJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgZm9vID0gKCkgPT4ge1xuICBjb25zb2xlLmxvZygnRnVja2VkIFVwJyk7XG59O1xuXG5leHBvcnQgY29uc3QgYmFyID0gKCkgPT4ge1xuICBjb25zb2xlLmxvZygnQmV5b25kIEFsbCBSZXBhaXInKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/outer.js\n");

/***/ })

其中有2行注释说明了:

/*! exports provided: foo, bar */
/*! exports used: foo */

就是打包文件中还是导出了foobar两个方法,但只用到了foo,这说明在development中代码的tree shaking只是找出来了并告知了,但并没有真的去删除这部分没用到的代码,webpack4新增了mode,将其设置为production后,不用设置optimization,就会真实执行tree shaking

// webpack.config.js
mode: 'production',

因为设置了mode: 'production'后代码被作了minify(压缩)mangle(混淆破坏)foobar方法已经搜不到了,但是方法体中的console内容还是可以搜的,可以发现,foo中的console内容Fucked Up还可以搜到,而bar中的console内容Beyond All Repair已经搜不到了,因为已经被删除了。

webpack4新增了一个例外处理的口子,就是在package.json中配置一个sideEffects属性,来设置哪些文件是永远都不会被删除掉的,如果设置了sideEffects: false,那么则会正常的删除未被用到的代码。如果设置了sideEffects: ["@babel/polly-fill"]则表明,即便@babel/polly-fill没被直接应用,但还是会在打包时,将它打包进来。

16、Mode: development/production

wenpack4新增了mode配置:

上一篇 下一篇

猜你喜欢

热点阅读