目前,我们的项目里已经有图片和js文件,但是我们项目肯定会有css文件。 如果遇到样式文件应该如何打包。

如何打包样式

结构
image.png

  1. import avatar from './avatar.jpg'
  2. import './index.css'
  3. var img = new Image();
  4. img.src = avatar;
  5. img.classList.add('avatar');
  6. var root = document.getElementById('root');
  7. root.append(img)
  1. .avatar {
  2. width:150px;
  3. height: 150px;
  4. }
  1. const path = require('path')
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. module: {
  8. rules:[
  9. {
  10. test: /\.(jpg|png|gif)$/,
  11. use:{
  12. loader: 'url-loader',
  13. options: {
  14. name:'[name]_[hash].[ext]',
  15. outputPath: 'images/',
  16. limit: 2048 // 2kb
  17. }
  18. },
  19. // 当我们打包css文件的时候一般需要两个loader
  20. {
  21. test: /\.css$/,
  22. // npm install style-loader css-loader -D
  23. use:['style-loader', 'css-loader']
  24. }
  25. }
  26. ]
  27. },
  28. output: {
  29. filename: 'bundle.js',
  30. path: path.resolve(__dirname, 'dist')
  31. }
  32. }

打包成功,样式成功应用
image.png
image.png
image.png

分析

  1. 首先我们引入了一个css文件,webpack肯定也不知道如何打包css
  2. 但是我们做了配置,webpack看到了css文件,就会css-loader以及style-loader帮我们打包。
  3. 打包好了之后,我们的js里面就有了样式相关的内容
  4. 然后因为我们给img标签添加了avatar的class名
  5. 所以他识别了class之后,通过style-loader帮我们把样式挂载到页面上。

style-loader以及css-loader的作用

我们先来改造一下
结构
新增了一个avatar.css
image.png

  1. .avatar {
  2. width:150px;
  3. height: 150px;
  4. }
  1. @import './avatar.css'
  1. import avatar from './avatar.jpg'
  2. import './index.css'
  3. var img = new Image();
  4. img.src = avatar;
  5. img.classList.add('avatar');
  6. var root = document.getElementById('root');
  7. root.append(img)

然后打包,效果肯定还是一样的
image.png
image.png
然后我们通过这里分析一下他们的作用 :::success css-loader
css-loader会帮我们分析出几个css文件之间的关系,最终把这些css文件合并成一段css
style-loader
在得到css-loader生成的css内容之后,style-loader会把这段内容挂载到页面的header部分 :::

所以在我们处理css这种文件打包的时候,我们一定要用css-loader配合style-loader一起来使用

image.png

其他格式的样式文件

:::info 如果我们在写项目的时候,可能会用到less,sass, scss等样式文件的时候,应该怎么打包处理 ::: 首先改造一下代码
结构
image.png

  1. body {
  2. .avatar {
  3. width:150px;
  4. height: 150px;
  5. }
  6. }
import avatar from './avatar.jpg'
import './index.scss'

var img = new Image();
img.src = avatar;
img.classList.add('avatar');

var root = document.getElementById('root');
root.append(img)

const path = require('path')
module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js'
  },
  module: {
    rules:[
      {
        test: /\.(jpg|png|gif)$/,
        use:{
          loader: 'url-loader',
          options: {
            name:'[name]_[hash].[ext]',
            outputPath: 'images/',
            limit: 2048 // 2kb
          }
        },
        // 当我们打包css文件的时候一般需要两个loader
        {
          test: /\.css$/,
          // npm install style-loader  css-loader -D
          use:['style-loader', 'css-loader']
        }
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

我们会发现,打包成功了,但是样式并没有改变
image.png
image.png
我们通过样式可以看出,这根本就不是css的语法,而是原始的scss语法,所以浏览器肯定不能识别。
image.png

正确的配置方式

:::info 我们还需要其他的loader帮助我们把scss的语法翻译成css的语法
sass-loader :::


const path = require('path')
module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js'
  },
  module: {
    rules:[
      {
        test: /\.(jpg|png|gif)$/,
        use:{
          loader: 'url-loader',
          options: {
            name:'[name]_[hash].[ext]',
            outputPath: 'images/',
            limit: 2048 // 2kb
          }
        },
        // 当我们打包css文件的时候一般需要两个loader
        {
          test: /\.css$/,
          // npm install sass-loader node-sass webpack --save-dev
          // node-sass 和 webpack 是 sass-loader 的 peerDependency(对等依赖),所以都要安装 
          // 当然这里我们npm install sass-loader node-sass --save-dev就可以了
          // 因为webpack我们已经安装了
          use:['style-loader', 'css-loader', 'sass-loader']
        }
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

顺序问题

:::info 在webpack的配置里面,loader是有先后顺序的。
loader的执行顺序是从下到上的(从右到左),也就是说会先执行sass-loader.

  1. 我们在打包一个scss文件的时候,会先执行sass-loader,对scss代码进行css翻译
  2. 翻译成css代码之后给到css-loader
  3. 然后css代码都处理好之后再给到style-loader挂载到页面上 :::

前缀问题

在我们书写一些css3的新特性的时候,很可能得不到浏览器的支持,我们一般都会写上前缀来获得支持。 那么我们如何使用webpack进行自动补全呢。

postcss-loader
通过官网我们可以知道,他要求我们写一个postcss.config.js文件,在这里面我们可以做一些配置。
然后我们发现配置里面有一个plugins(插件)的选项。
这个选项可以帮我们安装插件,例如: autoprefixer 自动前缀
image.png

写一下
结构
新增postcss.config.js文件
image.png

module.exports = {
  // 安装自动前缀插件
  // npm install autoprefixer -D 
  plugins: [ // 这里可用数组或对象
    require('autoprefixer')
  ]
}

body {
  .avatar {
    width:150px;
    height: 150px;
    // 使用css的新特性
    transform:translate(100px,100px);
  }
}

const path = require('path')
module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js'
  },
  module: {
    rules:[
      {
        test: /\.(jpg|png|gif)$/,
        use:{
          loader: 'url-loader',
          options: {
            name:'[name]_[hash].[ext]',
            outputPath: 'images/',
            limit: 2048 // 2kb
          }
        }
      },
      // 安装postcss-loader
      // postcss-loader  npm i -D postcss-loader
      {
        test: /\.scss$/,
        use:[
          'style-loader', 
          'css-loader',
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

:::info 这里的流程跟之前是一致的:

  1. 当webpack发现scss文件的时候,会先执行postcss-loader,然后回去寻找postcss.config.js配置文件
  2. 发现postcss.config.js配置文件中引用了 autoprefixer插件,然后就使用 autoprefixer
  3. 然后再执行其他的loader :::

结果我们发现还是不行。不是因为我们的配置写错了。

之所以没有前缀是因为,打包认为你在高级浏览器中使用这些特性,高级浏览器已经没必要加这些前缀了。所以如果要加,你在browserList里面加上老版本浏览器的兼容,那么打包就会给你加前缀了,你需要在webpack里面配置一个browserList的参数,

image.png
image.png

配置browserList

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "描述",
  "private": true,
  "scripts": {
    "bundle": "webpack"
  },
  "author": "chenYongRen",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^10.4.7",
    "css-loader": "^6.7.1",
    "file-loader": "^6.2.0",
    "node-sass": "^7.0.1",
    "postcss-loader": "^7.0.0",
    "sass-loader": "^13.0.0",
    "style-loader": "^3.3.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.9.2"
  },
  "dependencies": {},
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

image.png