Blog

懒癌晚期


Project maintained by VirusPC Hosted on GitHub Pages — Theme by mattgraham

Back Home

webpack: 常用loader与plugin


loader 与 plugin 概述

为什么需要 loader 和 plugin

webpack 是一个模块打包器。它的主要目标是将 JavaScript 文件打包在一起. 加载资源不再与index.html对话, 不再通过标签引入. 而是与 entry points (入口js文件)对话, 通过import引入资源.

webpack能直接加载的只有 js 和 json, 要想加载其他类型的资源(css, sass, ts, jpg, png 等)要使用loader, 想要更多功能(打包优化, 压缩等)需要plugin.

loader都是官方出品, 配置方法比较规范. plugin就不一定了.

不同环境的 loader 与 plugin

一般来说,我们会将配置文件拆成三部分:

  1. webpack.common.js: 开发环境和生产环境通用配置
  2. webpack.dev.js: 开发环境配置,用于 npm start
  3. webpack.prod.js: 生产环境配置,用于 npm run-script build

可以利用 webpack-merge 这个库,帮我们把通用配置,结合到另外两个配置里。

不同环境,使用的 loader 和 plugin 可能会不同。因为在开发环境中,我们考虑的是怎么让项目更方便的在本地跑起来,方便本地调试等。而在生产环境中,我们需要考虑代码打包后的体积,兼容性等。

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    //...
    modules: {
        rules:[
            {
                test: /\.css$/i,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.html$/i,
                loader: 'html-loader',
            },
        ],
        plugins:[
            new HtmlWebpackPlugin({
                template: './src/index.html'
            })
        ]
    }
}

如何找到合适的 loader 与 plugin

  1. 方法一: 官网上列出了一些优秀的loader与plugin(以及配置方法)
    • loader: https://webpack.js.org/loaders/ * plugin: https://webpack.js.org/plugins/
      • 利用 ctrl+f 在页面中搜索
  2. 方法二: 不知道用什么loader或plugin时, 可以参考React和Vue.

  3. 方法三: 根据用的工具 (如 typescript,sass) 的需求,借助搜索引擎。

loader 的使用

注意,在一个 rule 里配置多个 loader 时,执行顺序是从后到前。例如,配置 sass 文件的 loader 时,要把 sass-loader 放到 css-loader 等之后,这样就可以先让 sass-loader 将 sass 文件转为 css,再利用 css 相关 loader 进行进一步的处理。

  1. 安装
    • npm install -D xxx-loader
  2. 配置(webpack.config.js)
    • 暴露loader
      module.exports = {
          ...
          module: {
              rules: [
                  {
                      test: /(\.csv)$/  // loader要处理的文件的名字, 一般用正则表达式表示
                      loader: "file-loader"  // loader = loader名字/loader列表/外部引入模块提供的对象/自定义对象(包含loader和option等), 
                  }
              ]
          }
      }
      
  3. 导入文件
    • 直接在相应js文件中导入(而非在配置文件中导入)
      import "xxx.jpg";
      import "xxx.css";
      ...
      

plugin 的使用

  1. 安装
    • npm install xxx-plugin -D
  2. 配置(webpack.config.js)
    • 引入插件(CommonJS规范)
      const MyPlugin = require("my-plugin");  // 有些可能引入方式略有不同, 需要解构赋值等.
      module.exports = {
          // ...
          plugins: [
              new MyPlugin(params),
          ]
      };
      

3.一些 plugin 可能还提供了自己的 loader, 需要 plugin 和 loader 结合使用。 比如mini-css-extract-plugin。对于它们提供的loader,按照普通 loader 来配置。


开发环境的基本配置

打包样式资源

  1. 安装 loader

    • style-loader:用于在html文档中创建一个style标签, 将样式塞进去
    • css-loader:将css转换为CommonJS模块, 翻译 @import@url 并且解析它们。
  2. 配置 webpack:

     {
         test: /\.css$/i,
         use: [
             'style-loader',
             'css-loader'
         ]
     }
    
  3. 在入口文件中导入样式文件:

      import "index.css"
    

注意,不可以加载样式文件中的图片链接. 要加载需要额外的loader, 详见该部分: 打包图片资源

打包 HTML 资源

webpack不能解析html文件, 需要借助插件编译解析. 只有打包 html 不是用的 loader 而是plugin, 不走入口文件.

  1. 安装loader
    • html-webpack-plugin
      • 注意与html-loader区分开, 后者用于处理html中的标签资源
      • 注意不要在 html 中引入任何 css 和 js 文件
  2. 配置 webpack
    1. 注意多页面配置好各个页面对应的 chunks, 即 entry point.

打包图片资源

图片文件webpack不能解析, 需要借助loader编译解析. 前两个loader用于打包样式文件中的图片, 后一个loader用于打包html中的图片.

Url-loader vs File-loader

打包其他资源

除了js和json及上述资源外的其他资源(如字体文件), webpack也不能解析, 需要借助loader编译解析.

自动编译打包运行

live reload, 自动刷新整个页面. 想要局部刷新, 见HMR

typescript

  1. 安装基本库

     npm install -D typescript
    
  2. 在根目录下配置好 ts 的配置文件 tsconfig.json. 可参考官网手册 以及一些开源项目的配置。尤其注意配置好 ts 生效的文件夹。

  3. 安装其他库的类型库。比如如果有使用 jest 的话,执行 npm install -D @types/jest

  4. 安装 loader

     npm install -D ts-loader
    
  5. 配置 webpack

     {
       test: /\.tsx?$/,
       use: 'ts-loader',
       exclude: /node_modules/,
     },
    

sass

  1. 安装基本库

     npm install -D node-sass # provides binding for Node.js to LibSass, a Sass compiler.
     或
     npm install -D sass  # dark sass
    
  2. 安装 loader

     npm install -D style-loader css-loader sass-loader
    
  3. 配置 webpack,将 sass-loader 串到 css 相关 loader 的后面。
     {
       test: /\.(scss|sass|css)$/,
       use: ['style-loader', 'css-loader', 'sass-loader'],
     },
    
  4. 在文件中直接引用
     import 'xxx.sass'
    

生产环境的基本配置

本节提到的plugin只安装在webpack.prod.js, 不安装在webpack.dev.js.

提取 css 成单独文件

默认不装插件的情况下, import 样式表, 会直接将其转化为内联样式, 不会生成单独的css文件.

css 兼容性处理

压缩 css

调成production模式只能压缩js, 不能压缩css. 想要压缩css, 我们需要借助其他的插件.

js 兼容性处理

有些浏览器不支持新特性, 需要将浏览器不能识别的新语法转换成原来识别的旧语法(es6->es5),做浏览器兼容性处理.

js 压缩

HTML 压缩


优化配置

js 语法检查

对js基本语法错误, 或是隐患, 进行提前检查

HMR

HMR(Hot Module Replacement, 热模替换, 模块热更新)可以实现局部刷新(对比webpack-dev-server自带的live reload, 真个页面刷新). 它允许在运行时更新所有类型的模块, 而无需完全刷新(只更新变化的模块, 不变化的模块不更新).

source-map

我们发布到生产环境的代码,一般都有如下步骤:

这三个步骤,都使得实际运行的代码不同于开发代码,不管是 debug 还是捕获线上的报错,都会变得困难重重。

解决这个问题的方法,就是使用sourceMap。

简单说,sourceMap就是一个文件,里面储存着位置信息。仔细点说,这个文件里保存的,是转换后代码的位置,和对应的转换前的位置。有了它,出错的时候,通过断点工具可以直接显示原始代码,而不是转换后的代码。

清空打包文件目录

在与他人协作编程时, 其他人可能会不小心直接向打包文件夹中添加文件, 这样的话该文件在下次重新打包后并不会被删除. 每次打包生成了新的文件, 都需要手动删除之前的文件, 引入插件帮助我们自动删除上一次的文件.

oneOf

缓存

tree shaking

code-split

lazy-loading

pwa

多进程打包

externals


参考资料: