wabpack 中 loader 和 plugins 的区别

前言

webpack 是现在最流行的打包工具。使用过 webpack 的人对 loader 与 plugins 一定不会陌生。虽然在 webpack 中万物皆模块,但是 webpack 真正认识的也只不过 js 文件而已。那么其他的文件比如 CSS 或者图片也想打包成模块应该怎么办呢,这就需要借助 loader 工具了。 另外,如果想对文件进行压缩减小体积应该怎么办呢,这时候 plugins 就可以登场了。那么 loader 与 plugins 到底有什么区别呢?

1. loader

1.1 loader 职能

loader 主要提供编译或者转换的职能。

  • babel-loader :将 ES6 语法编译成 ES5 语法。
  • style-loader 和 css-loader:编译 CSS 语法(前面提到 webpack 只认识 JS 文件)。这两个 loader 可以将 CSS 文件插入到 <style></style> 中。
  • postcss-loader:在样式前加浏览器前缀。
  • less-loader :将 Less 语法编译成普通的 CSS 语法。
  • sass-loader :将 Sass 语法编译成普通的 CSS 语法。
  • url-loader :将图片文件转换成 Base64 字符串,这样可以有效地减少 HTTP 请求。
  • file-loader :没有转换成 Base64 的文件(通常是比较大的文件)就使用该 loader 进行编译。
    url-loader 依赖于 file-loader。其功能是建立在 file-loader 基础之上的。配置 url-loader 时会有一个 limit 属性。假设 limit 属性值为 10000,则表示在10000B以内的文件会转换成 Base 64 字符串。从而减少请求提升性能。而大于 10000B 以内的文件就由 file-loader 从服务器作为静态资源调用。

1.2 loader 配置

配置示例:

 module:{
         rules:[
                {
                    test: /\.js$/,//正则匹配文件类型
                    loader: 'babel-loader?cacheDirectory=true',//使用的 loader
                    include: [
                      resolve('src'),//包含的文件夹
                    ],
                    exclude:path.resolve(__dirname, 'node_modules')//排除的文件夹
                 },
                {
                    test:/\.css$/,
                    use:[
                        'style-loader',
                        'css-loader',
                        'postcss-loader'
 
                    ]
                },
                {
                    test:/\.(png|svg|jpg|gif)$/,
                    loader: 'url-loader',
                    options: {
                      limit: 10000,
                      name: utils.assetsPath('img/[name].[hash:7].[ext]')
                    }
                }
            ]
        }

loader 参数解析:
test 表示正则匹配。
loader 表示要使用的loader,babel-loader?cacheDirectory=true 表示未更改的 babel 将会被缓存,可以加快打包速度。
use 表示需要用到的 loader 组。
include 表示只搜索该文件夹下的文件。
exclude 表示排除某个目录下的文件。
options 其他配置项,limit 表示区间值大小限制。比如图片格式配置了此项则在此区间内的图片会转换成 Base 64 字符串,name 表示打包之后的路径及名称。

2. plugins

2.1 plugins 职能

plugins 主要是拓展 webpack 功能,某种程度上也可以理解为是对 webpack 的一种优化。

  • html-webpack-plugin:生成 HTML 模板,并将打包后的 JS 和 CSS 文件使用 script 标签和 link 标签引入。
const HtmlWebpackPlugin= require('html-webpack-plugin')
new HtmlWebpackPlugin({
    title:"react-app",//生成 html 模板的标题
    template:'./index.html',//模板路径
    filename:index.html,//模块文件名
    inject:true,//向模板中引入静态资源。
    //true 表示所有JavaScript资源插入到body元素的底部,
    //head 表示所有JavaScript资源插入到body元素的头部 head 中,
    //false 表示不会引入静态资源
    favicon:false,//添加特定favicon 路径到 html 模板中
    hash:true, //是否为静态资源添加hash值
    chunks:'all',//是否为模板加入所有的chunks,如果时多页面应用,需要单独配置不同的chunk。    
  }),
  • extract-text-webpack-plugin:将 JS 中的 CSS 抽离出来,成为单独的 CSS 文件,JS 与 CSS 并行下载;
const ExtractTextPlugin = require('extract-text-webpack-plugin')
 module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",//如果提取失败,就使用 style-loader 提取到页面的style 标签中
          use: "css-loader"//使用的 loader 配置
        })
      }
    ]
  },
  plugins: [
  new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[hash].css'),//文件路径
      allChunks: true,//是否抽取其他附加的 chunks 的style。
    }),
  ]
  • commons-chunk-plugin:提取第三方库或者公共资源到单独的模块,避免 bundle文件过大,导致首屏或者按需加载太慢;在 webpack 4 中使用内置的 splitChunks 进行配置。
 output: {
        ...........
        chunkFilename: "[name].[hash:7].chunk.js",
    },
 new webpack.optimize.CommonsChunkPlugin({
      name: 'app',//chunk 名称
      async: 'vendor-async',//异步加载children模块
      children: true,//通过入口文件抽离chunk,与chunks不能同时设置
      chunks:[],//从哪些业务模块中抽离chunk,与children不能同时设置
      minChunks: 3//模块被多少个公共chunk引用才被抽离出来作为单独的chunk
    }),
  • DLLPlugin 和 DllReferencePlugin :对不经常改动的库进行单独配置,减少打包次数。
    首先需要单独配置一个webpack.config.dll.js文件,在该文件中配置 DLLPlugin。其次在 package.json 中的 scripts 配置项中添加命令 "dll":"node_modules/.bin/webpack --config build/webpack.config.dll.js",,然后执行该命令。打包生成 manifest.json 文件。
const path = require('path');
const DllPlugin = require('webpack/lib/DllPlugin');
module.exports = {
  entry:{
    vendor:['vue','element-ui','vue-router','axios'],
  },
  mode:"production",
  output:{
    filename:'[name].js',
    path: path.resolve(__dirname, '../public/static/lib'),
    library:'[name]',  //dll的全局变量名
  },
  plugins:[
    new DllPlugin({
      name:'[name]',  //dll的全局变量名
      path:path.join(__dirname,'../public/static/lib','[name].manifest.json'),//描述生成的manifest文件
    })
  ]
}

在 webpack.base.conf 配置中引用 manifest.json 文件。

const manifest = require('../public/static/lib/vendor.manifest.json');
  new DllReferencePlugin({
      manifest
    }),
  • optimize-css-assets-webpack-plugin :对 CSS 进行压缩,最小化处理。
 new OptimizeCSSPlugin({
      assetNameRegExp:/\.css$/g,//正则表达式,匹配需要压缩的资源。
      cssProcessor:require('cssnano'),//用于压缩和优化CSS 的处理器。
      cssProcessorOptions: { safe: true },
      canPrint:true,//表示能否在console.log中打印信息。
    }),
  • uglifyjs-webpack-plugin :对 JS 进行压缩(webpack 4已废弃,不再维护);在 webpack 4 中使用 teaser-webpack-plugin 进行压缩。
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
    new UglifyJsPlugin({
       test: /\.js(\?.*)?$/i,  //测试匹配文件,
       include: /\/includes/, //包含哪些文件
       excluce: /\/excludes/, //不包含哪些文件
       uglifyOptions: {
        compress: {
          warnings: false //是否有warning提示
        }
      },  
      sourceMap: false,//使用sourceMap将错误消息位置映射到模块(这会减慢编译速度)
      //允许过滤哪些块应该被压缩(默认情况下,所有块都是会被压缩)。 
      //返回true以uglify块,否则返回false。
      chunkFilter: (chunk) => {
            // `vendor` 模块不压缩
            if (chunk.name === 'vendor') {
              return false;
            }
            return true;
          }
      cache: false,//是否启用文件缓存,默认缓存在node_modules/.cache/uglifyjs-webpack-plugin.目录
      parallel: true,//使用多进程并行运行来提高构建速度     
})],

terser-webpack-plugin 参数同 uglifyjs-webpack-plugin

const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
    new TerserPlugin({
        test: /\.js(\?.*)?$/i,//要匹配的文件类型
        parallel: true,//使用多进程并行运行来提高构建速度     
})],
  },
};

2.2 plugins 配置

plugins:[
  new HtmlWebpackPlugin({
    template:'./index.html',
    filename:index.html,
    chunks: ['manifest', 'vendor', filename],
  }),
  new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),
  new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
  new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[hash].css'),
      allChunks: true,
    }),
  new OptimizeCSSPlugin({
      cssProcessorOptions:{ safe: true }
    }),
  new DllReferencePlugin({
      manifest
    }),
]
发布了252 篇原创文章 · 获赞 2360 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/weixin_44135121/article/details/103387869
今日推荐