webpack入门(三)

181 阅读2分钟

loader

loader是干什么用的呢?实际上,webpack在打包过程中,只能认识js和json文件,如遇到css和图片等类型的文件,他并不能识别,无法进行继续打包,会抛出错误。loader的作用就是让webpack去处理一些除了js和json文件类型以外的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中

在 webpack 的配置中,loader 有两个属性:

test 属性,识别出哪些文件会被转换。 use 属性,定义出在进行转换时,应该使用哪个 loader。

我们来看一个简单的loader使用例子:

npm install raw-loader -D
module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      { 
        test: /\.txt$/,
        use: 'raw-loader'
      }
    ],
  },
};

loader的使用我们放在module属性下的rules中,module顾名思义就是模块的意思,这里我们处理的都是模块的内容,rules就是规则,他是一个数组,配置不同规则,可以处理不同的文件类型。

loader处理样式

假如我们现在有以下逻辑代码:

import './index.css';

let root = document.getElementById('root');
root.classList.add('demo');

现在我们要对上面这个js文件进行打包,很显然,打包的时候会报错,因为webpack打包的时候遇到css文件类型,他无法识别,我们也没告诉他,如果遇到css文件类型,应该如何处理,所以,我们在webpack.config.js中进行配置:

npm install css-loader style-loader -D
module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      { 
        test: /\.txt$/,
        use: 'raw-loader'
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      }
    ],
  },
};

进行了以上的配置之后,再进行打包,我们就会发现,打包成功了,我们经过配置,就是告诉了webpack,在打包的时候,如果遇到 .css 结尾的文件,就使用 style-loader , css-loader 这两个loader进行处理,那这两者在使用的时候有没有顺序呢,答案是:有的,webpack在处理的时候,是按照我们在use中配置的数组项中从下到上或者从右到左进行挨个处理的,这里,也就是先用css-loader处理,处理完后,再用style-loader处理。

那么还有一个问题,为什么我们要使用style-loader呢?其实style-loader的作用是把css-loader处理好的css样式挂载到html文档中的head元素中的<style></style>元素中,这样,html的样式才能生效

再来看下面这个css文件:

// index.css

@import './sub.css'

// sub.css

.demo{
  background-color: #eee;
}

我们在index.css文件中又使用import引入了另一个css文件,然后进行打包,浏览器打开html文件,样式上面没有问题,然后我们做如下的配置:

module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      { 
        test: /\.txt$/,
        use: 'raw-loader'
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              import: false
            }
          }
        ]
      }
    ],
  },
};

继续打包,浏览器打开html文件,发现,我们需要的样式不生效了。这里,我们可以发现,loader还可以通过options属性来配置我们需要的各项能力,这里的import属性,就是来启用/禁用 @import 解析的,我们设置成了false,css文件中的@import就无法解析了

我们实际开发中也会用scss或者less文件来处理样式,那么scss文件我们改如何配置呢,下面也是一个简单处理scss文件的配置:

npm install sass-loader node-sass -D

我们需要使用上面两个包

module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              import: false
            }
          }
        ]
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader',
        ]
      }
    ],
  },
};

同样的,在use中的使用顺序是,先使用sass-loader将scss文件处理成css文件,再用css-loader处理css文件,最后使用style-loader将css文件内容挂到style元素中去

接下来我们再介绍一个postcss-loader:

npm install --save-dev postcss-loader postcss

按照官方推荐,我们可以在与webpack.config.js同级目录下,新建一个postcss.config.js文件,这里我们也顺带介绍一下autoprefixer这个插件,可以先npm install autoprefixer -D来安装一下这个插件,然后我们在postcss.config.js中使用这个插件:

// postcss.config.js
module.export = {
  plugins: [
    require('autoprefixer')
  ]
}
module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              import: false
            }
          }
        ]
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2
            }
          }
          'sass-loader',
          'postcss-loader'
        ]
      }
    ],
  },
};

PostCSS 可以处理 CSS 的 loader,怎么处理呢?我们通过使用autoprefixer这个插件来举例,这个插件可以帮助我们在css属性前面自动加上-webkit-等浏览器属性。

loader处理图片文件

处理图片文件,我们需要使用file-loader

module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: [name].[ext]  // [hash]
            }
          }
        ]
      }
    ],
  },
};

还有一个url-loader也可以处理图片文件

module.exports = {
  entry: 'src/index.js',
  output: {
    filename: 'bundle.js',
    path: './dist'
  },
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 20800
            }
          }
        ]
      }
    ],
  },
};

url-loader和file-loader的区别是什么呢?file-loader是直接将原图片打包至output的文件目录中,而url-loader则是直接将图片转化成base64直接放入在js文件中,但我们可以通过limit来配置,图片大小小于我们配置的limit,则会转化成base64,否则还是以图片打包到output的文件目录

好了,这里我们就是简单介绍了loader的作用,大概知道了loader能干什么,至于更具体的每一个loader的使用方法和配置项,还是需要参考官方的文档,那里会更细更具体,在使用webpack过程中按需去查找即可