分享

Webpack教程四:Loader

 小小小舟 2019-12-09

目录

一、什么是Loader

二、打包图片

2.1、file-loader

2.2、url-loader

2.3、file-loader和url-loader的比较

三、打包CSS文件

3.1、style-loader和css-loader

3.2、sass-loader

3.3、postcss-loader

3.4、处理sass文件中引入另外sass文件的情况

3.5、CSS模块化

四、打包字体、图标


一、什么是Loader

    前面章节已经展示了如何使用webpack打包js文件,那么怎么使用webpack打包其他类型的文件呢?(比如图片、css样式文件、json文件等等)

    答案是使用loader,webpack最出色的功能之一就是,除了能引入js文件之外,还可以通过loader引入任何其他类型的文件。

    因此,loader是一个打包方案,能对特定类型的文件用相应的方案进行打包。

二、打包图片

    webpack的loader机制支持打包图片,打包图片主要用到的两个loader是file-loaderurl-loader

2.1、file-loader

    我们先来看file-loader

    首先,先安装file-loader

   然后,清空webpack-demo目录下的src文件夹,并随便放入一张图片:

   在src文件夹中再加入一个index.js文件:

   index.js:

  1. import Icon from './dog.jpg';
  2. console.log(Icon);
  3. var element = document.getElementById('webContent');
  4. var icon = new Image();
  5. icon.src = Icon;
  6. element.appendChild(icon);

    然后,为了让file-loader能够起作用,还需配置wepback.config.js文件:

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [
  16. 'file-loader' // 使用的loader
  17. ]
  18. }
  19. ]
  20. }
  21. }

    最后,进行打包操作:

   打包后生成了一个新的以哈希值命名的图片文件,可以在dist文件夹中找到:

    我们可以使用浏览器打开dist.html

    图片已经被成功打包,并在项目中显示出效果了!

    另外,还可以对file-loader进行更多配置:

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'file-loader', // 使用的loader
  17. options: {
  18. name: '[name].[ext]' // 打包出的图片文件仍保持原有命名
  19. }
  20. }]
  21. }
  22. ]
  23. }
  24. }

    进行打包操作:

    可以看到生成的图片文件文件名与原始文件一致。

2.2、url-loader

    还可以使用url-loader来打包图片,它与file-loader的不同之处在于url-loader将图片打包成base64的形式加载到main.js文件中。

    首先,让我们来安装url-loader:

    然后,重新配置webpack.config.js

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. }
  22. ]
  23. }
  24. }

    进行打包操作:

    可以明显发现,这次打包没有生成新图片文件,这是因为dog.jpg这个图片文件大小只有8kb,所以url-loader以base64的形式对该图片文件进行打包。

    我们打开main.js文件:

    可以发现,图片真的以base64位的形式被打包,并被加载到main.js文件中。

    可以用浏览器打开dist.html文件:

    效果和之前一致!

2.3、file-loader和url-loader的比较

    file-loader实际上只将图片进行了文件目录的转移,而ulr-loader却可以将图片文件以base64位的形式进行处理,因此:

  • 当图片很小时    ——    适合用url-loader,因为图片将以base64位的形式加载到main.js,因此浏览器将只请求一个main.js文件,而不用多发起一次对图片的http请求。

  • 当图片比较大时    ——    适合用file-loader,因为能让main.js更快地加载出来。

三、打包CSS文件

3.1、style-loader和css-loader

    为了让webpack能够打包css文件,需要安装style-loadercss-loader,并对webpack.config.js进行配置。

    先来安装style-loader和css-loader:

    再对webpack.config.js进行配置:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. },
  22. {
  23. test: /\.css$/,
  24. use: [
  25. 'style-loader',
  26. 'css-loader'
  27. ]
  28. }
  29. ]
  30. }
  31. }

    现在就可以来测试一下webpack能不能打包css文件了,首先在src文件夹下创建一个dog.css文件:

    dog.css:

  1. .dog {
  2. width: 300px;
  3. height: 300px;
  4. }

    修改index.js

    index.js:

  1. import Icon from './dog.jpg';
  2. import './dog.css';
  3. var element = document.getElementById('webContent');
  4. var icon = new Image();
  5. icon.src = Icon;
  6. icon.classList.add('dog');
  7. element.appendChild(icon);

    进行打包:

    用浏览器打开dist.html,可以发现css样式文件已经起作用:

3.2、sass-loader

    webpack不仅可以打包css文件,还可以打包sass文件,不过需要sass-loader

    首先安装sass-loader:

    再配置webpack.config.js

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. },
  22. {
  23. test: /\.scss$/,
  24. use: [
  25. 'style-loader',
  26. 'css-loader',
  27. 'sass-loader'
  28. ]
  29. }
  30. ]
  31. }
  32. }

    现在可以测试webpack能不能打包sass文件,首先修改dog.css文件名为dog.scss,然后再修改dog.scss内容:

    dog.scss

  1. body {
  2. .dog {
  3. width: 300px;
  4. height: 300px;
  5. }
  6. }

    进行打包:

    再用浏览器打开dist.html,可以发现效果与之前一样:

3.3、postcss-loader

    许多css样式的书写需要添加厂商前缀,我们可以使用postcss-loader来完成添加厂商前缀的操作,但现在我们先来看不添加厂商前缀的示例。

    修改dog.scss文件:

    dog.scss:

  1. body {
  2. .dog {
  3. width: 300px;
  4. height: 300px;
  5. transform: translate(100px, 100px);
  6. }
  7. }

    进行打包,然后用浏览器打开dist.html

    果然有偏移效果,在浏览器中查看样式:

    可以发现,transform之前并没有添加前缀,接下来我们使用postcss-loader来让transform之前添加厂商前缀。

    首先,安装postcss-loader:

   因为还需要autoprefixer插件的配合,所以安装autoprefixer

   然后在webpack-demo根目录创建一个postcss.config.js,并为其添加内容:

    postcss.config.js:

  1. module.exports = {
  2. plugins: [
  3. require('autoprefixer')
  4. ]
  5. }

    再配置webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. },
  22. {
  23. test: /\.scss$/,
  24. use: [
  25. 'style-loader',
  26. 'css-loader',
  27. 'sass-loader',
  28. 'postcss-loader'
  29. ]
  30. }
  31. ]
  32. }
  33. }

    进行打包:

   用浏览器打开dist.html,可以发现transform已经添加了厂商前缀:

3.4、处理sass文件中引入另外sass文件的情况

    在webpack打包sass文件的过程中,它内部调用的loader的顺序是postcss-loader、sass-loader、css-loader和style-loader,也就是webpack.config.js文件中从use数组中从下往上调用:

    现在,在src根目录创建一个dog2.scss文件:

    dog2.scss:

  1. body {
  2. .dog {
  3. transform: translate(100px, 100px);
  4. }
  5. }

    再修改dog.scss文件:

    dog.scss:

  1. @import './dog2.scss';
  2. body {
  3. .dog {
  4. width: 300px;
  5. height: 300px;
  6. }
  7. }

    因为dog2.scss作为引入的方式加载到dog.scss,所以webpack会直接调用css-loader,而不会在调用css-loader之前先调用postcss-loader和sass-loader,为了解决这个问题,可以对css-loader进行配置:

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. },
  22. {
  23. test: /\.scss$/,
  24. use: [
  25. 'style-loader',
  26. {
  27. loader: 'css-loader',
  28. options: {
  29. importLoaders: 2
  30. }
  31. },
  32. 'sass-loader',
  33. 'postcss-loader'
  34. ]
  35. }
  36. ]
  37. }
  38. }

    现在可以进行打包了:

3.5、CSS模块化

    webpack支持CSS模块化,具体是什么意思呢?

    在src根目录下,创建一个createImg.js:

    createImg.js:

  1. import Icon from './dog.jpg';
  2. function createImg() {
  3. var element = document.getElementById('webContent');
  4. var icon = new Image();
  5. icon.src = Icon;
  6. icon.classList.add('dog');
  7. element.appendChild(icon);
  8. }
  9. export default createImg;

    修改src目录下的index.js:

    index.js:

  1. import Icon from './dog.jpg';
  2. import './dog.scss';
  3. import createImg from './createImg.js';
  4. createImg();
  5. var element = document.getElementById('webContent');
  6. var icon = new Image();
  7. icon.src = Icon;
  8. icon.classList.add('dog');
  9. element.appendChild(icon);

    进行打包:

    然后用浏览器打开dist.html:

    可以发现,新创建的图片和之前的图片有相同的样式,也就是dog.scss样式文件中指定的效果。

    现在我们想让只有其中的一张图片具有dog.scss文件中的样式,这也就是CSS模块化的意思,只将某个CSS文件作用于页面中的某些部分

    可以这样来做,首先修改webpack.config.js文件以开启CSS模块化:

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. },
  22. {
  23. test: /\.scss$/,
  24. use: [
  25. 'style-loader',
  26. {
  27. loader: 'css-loader',
  28. options: {
  29. importLoaders: 2,
  30. modules: true
  31. }
  32. },
  33. 'sass-loader',
  34. 'postcss-loader'
  35. ]
  36. }
  37. ]
  38. }
  39. }

    再修改index.js文件:

    index.js:

  1. import Icon from './dog.jpg';
  2. import style from './dog.scss';
  3. import createImg from './createImg.js';
  4. createImg();
  5. var element = document.getElementById('webContent');
  6. var icon = new Image();
  7. icon.src = Icon;
  8. icon.classList.add(style.dog);
  9. element.appendChild(icon);

    进行打包,然后用浏览器打开dist.html文件:

    可以发现,dog.scss文件样式只作用于其中的一张图片。

四、打包字体、图标

    如何使用webpack来打包字体和图标呢?

    我们可以去阿里巴巴矢量图标库下载图标来测试一下。

    这里我随便下载了一个图标:

    在webpack-demo的src文件夹下新建一个fonts文件夹,将iconfont.eot、iconfont.svg、iconfont.ttf、iconfont.woff、iconfont.woff2这几个文件拷贝进去。

    然后在src文件夹下新建一个iconfont.scss,将iconfont.css里的全部内容复制到iconfont.scss里,并作路径修改:

    iconfont.scss

    修改index.js:

    index.js:

  1. import './iconfont.scss';
  2. var webContent = document.getElementById('webContent');
  3. webContent.innerHTML = '<i class="iconfont iconWIFI"></i>';

    最后,还要修改webpack.config.js:

    webpack.config.js:

  1. const path = require('path');
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. output: {
  8. filename: 'main.js',
  9. path: path.resolve(__dirname, 'dist')
  10. },
  11. module: {
  12. rules: [
  13. {
  14. test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
  15. use: [{
  16. loader: 'url-loader', // 使用的loader
  17. options: {
  18. limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
  19. }
  20. }]
  21. },
  22. {
  23. test: /\.scss$/,
  24. use: [
  25. 'style-loader',
  26. {
  27. loader: 'css-loader',
  28. options: {
  29. importLoaders: 2
  30. }
  31. },
  32. 'sass-loader',
  33. 'postcss-loader'
  34. ]
  35. },
  36. {
  37. test: /\.(woff|woff2|eot|ttf)$/,
  38. use: [
  39. 'file-loader'
  40. ]
  41. }
  42. ]
  43. }
  44. }

    现在可以进行打包了:

    使用浏览器打开dist.html

    图标显示出来了!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多