webpack系列---loader

289 阅读3分钟

一. loader是什么及作用

A loader is a node module exporting a function。

webpack本身只能打包Javascript文件,对于其他资源例如 css,图片,或者其他的语法集比如jsx,是没有办法加载的。 这就需要对应的loader将资源转化,加载进来。

所谓 loader 只是一个导出为函数的 JavaScript 模块。
loader runner
会调用这个函数,然后把上一个 loader 产生的结果或者资源文件(resource file)传入进去。函数的 this 上下文将由 webpack 填充,并且
loader runner
具有一些有用方法,可以使 loader 改变为异步调用方式,或者获取 query 参数。

第一个 loader 的传入参数只有一个:资源文件(resource file)的内容。compiler 需要得到最后一个 loader 产生的处理结果。这个处理结果应该是 String 或者 Buffer(被转换为一个 string),代表了模块的 JavaScript 源码。另外还可以传递一个可选的 SourceMap 结果(格式为 JSON 对象)。

如果是单个处理结果,可以在同步模式中直接返回。如果有多个处理结果,则必须调用 this.callback()。在异步模式中,必须调用 this.async(),来指示
loader runner
等待异步结果,它会返回 this.callback()回调函数,随后 loader 必须返回 undefined 并且调用该回调函数。

一. 常用loader

样式

  1. css-loader : 解析css文件中代码

  2. style-loader : 将css模块作为样式导出到DOM中

  3. less-loader : 加载和转义less文件

  4. sass-loader : 加载和转义sass/scss文件

脚本转换编译

  1. script-loader : 在全局上下文中执行一次javascript文件,不需要解析

  2. babel-loader : 加载ES6 代码后使用Babel转义为ES5后浏览器才能解析

Files文件

1.url-loader : 多数用于加载图片资源,超过文件大小显示则返回data URL

2.raw-loader : 加载文件原始内容(utf-8格式)

加载框架

1、vue-loader : 加载和转义vue组件

2、react-hot-loader : 动态刷新和转义react组件中修改的部分

一. loader问题

1、配置项module的rules中同一个test下的use中的loader的优先级:优先处理的loader放在配置数组的后面,例:

{      
test: /\.scss$/,
  use: [
  'vue-style-loader',
  'css-loader',
  'postcss-loader',
  'sass-loader'
  ]
}
loader的执行顺序是:sass-loader --》 postcss-loader --》 css-loader --》 vue-style-loader 

2、不同test内的优先级:可以用enforce:’pre’强调优先级

module: {
  rules: [
      {
        // 匹配less文件
        test: /\.css$/,
        // 匹配多个文件
        test:[
          /\.less$/,
          /\.css$/
        ],
        // 不会编译 node_modules 目录下的文件
        exclude: path.resolve(__dirname, 'node_modules'),
        // 只编译中src目录里的文件
        include: path.resolve(__dirname, 'src')
         // 匹配类似foo.css?inline的带有?inline的css
        resourceQuery: /inline/,
    },
    {
        // ?cacheDirectory 表示传给 babel-loader 的参数,
        // 用于缓存 babel 编译结果加快重新编译速度
        use: ['babel-loader?cacheDirectory'],
        // 这种方法同上面的方法,当loader需要传入很多参数时
        // 可以使用options对象
        user:[
            {
                loader:'babel-loader', 
                options:{ // 将query形式转换成options对象
                    cacheDirectory:true
                }
            }
        ],
        // 处理顺序为从后到前,即先交给 less-loader 处理,
        // 再把结果交给 css-loader 最后再给 style-loader。
        use: ['style-loader', 'css-loader', 'less-loader'],
        
    },
    {
         // 匹配less文件
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
        //将安照从左往右顺序执行loader。
        enforce: 'pre'
    },
    {
        test: /.css$/,
        //只使用第一个匹配规则
        oneOf: [
            {
             // 匹配类似foo.css?inline的带有?inline的css
                resourceQuery: /inline/,
                use: 'url-loader'
            },
            {
             // 匹配类似foo.css?external的带有?external的css
                resourceQuery: /external/,
                use: 'file-loader'
            }
        ]
    }
  ]
}

3、ccs 压缩后, z-index 被重写

webpack4 已经不支持用extract-text-webpack-plugin来优化 css, 需要改成optimize-css-assets-webpack-plugin和mini-css-extract-plugin, 如果你直接这么配置:

// 那么z-index将会被重写
optimization: {
    // 略
    minimizer: [
        new OptimizeCSSAssetsPlugin({})
    ]
    // 略
},

// 修改后
optimization: {
    minimizer: [
        new OptimizeCSSAssetsPlugin({
            cssProcessorOptions: {
                discardComments: { removeAll: true },
                // 避免 cssnano 重新计算 z-index
                safe: true
            }
        })
    ]
},