webpack成长指北第8章---webpack的CSS Modules打包

简介: webpack成长指北第8章---webpack的CSS Modules打包


何为CSS Modules

CSS Modules,样式的模块化,实际上就是所有的类名都只有局部作用域的CSS文件,其有以下几个特点

  • 所有样式都是局部化,解决命名冲突和全局污染的问题
  • class类名生成规则配置灵活,可以借此压缩class类名
  • 只需引入组件的js,就能搞定组件所有的js和css

案例

我们先编写我们的项目代码

  • 项目目录

  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- 解决没有favicon.ico时报错GET http://localhost:9999/favicon.ico 404 (Not Found) -->
  <link rel="shortcut icon" href="#" />
  <link type="text/css" rel="styleSheet" href="./dist/css/main.css" />
  <title>webpack学习</title>
</head>
<body>
  <div>这是webpack学习</div>
  <div id="root"></div>
  <script src="./dist/main.js"></script>
</body>
</html>
  • index.js
import module1 from './src/components/module1.js';
import module2 from './src/components/module2.js';
module1();
module2();
  • module1.js
import '../assets/style/index.css';
function module1 () {
  const dom = document.getElementById('root');
  const styleShowCssOne = document.createElement('div');
  styleShowCssOne.innerText = '模块1';
  styleShowCssOne.className = 'red-font-css'
  dom.append(styleShowCssOne);
}
export default module1;
  • module2.js
function module1 () {
  const dom = document.getElementById('root');
  const styleShowCssOne = document.createElement('div');
  styleShowCssOne.innerText = '模块2';
  styleShowCssOne.className = 'red-font-css'
  dom.append(styleShowCssOne);
}
export default module1;
  • index.css
.red-font-css {
  color: red;
}
  • webpack.config.js
const path = require('path'); // 由于webpack无法直接操作文件夹,所以需要引入node的path模块
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // webpack默认是将css打包到js中,如果需要将css打包成单独文件,则需要引入它
module.exports = {
  entry: {
    main: './index.js', // 指定当前目录的index.js为打包的入口文件
                       // 实际上是 entry: './index.js' 的具体写法,main为打包的Chunk Name
  },
  mode: 'development', // mode  指定打包模式(development(不会被压缩),production(这个模式的话代码会被压缩))
                       // development默认配置了sourcemap
                       // development默认无tree shaking配置,需要额外配置
  plugins: [
    new MiniCssExtractPlugin({   // 如果需要将css打包成单独文件,则需要引入它
      filename: './css/main.css', // 非必填,默认当前目录main.css,如指定路径和文件名可这样填写
      chunkFilename: '[id].css',  // 间接引入css的才会走chunk.filename
    }),
  ],
  module: {
    rules: [
      // 将css打包成单独文件
      {
        test:/\.css$/,
        use:[
            {
              loader: MiniCssExtractPlugin.loader, // mini-css-extract-plugin是将css打包成独立的文件的插件
              options: {
                publicPath: '../../' // 设置publicPath,这样css引用的背景图url就会以css所在的文件为基础
              }
            },
            {
              loader: 'css-loader', //将 CSS 转化成 CommonJS 模块
              options: {
                import: true, // 启用/禁用 @import 处理
              }
            },
            'postcss-loader'  // 在css3新特性下,我们是要添加浏览器厂商前缀的。如果没有浏览器厂商前缀,同一套样式不同浏览器展现的样式是不同的。
        ]
      },
    ]
  },
  output: {
    filename: '[name].js', // 打包后输出的打包文件的文件名,根据entry的chunk name作为输出文件名(如果entry有多个入口文件时必须用占位符这样设置output.filename)
    path: path.resolve(__dirname, 'dist'), // 指定打包后输出的打包文件在当前webpack.config.js所在文件夹的绝对路径的dist文件夹下
                                           // path值必须是绝对路径 ,所以引入path包,__dirname代表当前webpack.config.js所在文件夹的绝对路径
                                           // 整体路径为第一个参数+第二个参数,即__dirname + dist
                                           // 是所有输出文件的目标路径(物理路径, 存储路径);                  
    publicPath: 'dist/'   // (url 相对于 HTML 页面所在文件夹的绝对路径 + 值)给output配置全局的publicPath,
                          // 这样各个loader打包出来的文件发布路径(引用地址)就是此全局publicPath + loader的options.outputPath
                          // (文件引用路径就是看这个)
                          // 是对页面引入资源的补充,比如img标签引入或者css引入等.
                          // 千万不能设错,应该观察文件和HTML页面的存储地址位置,进行设置,否则引用时地址会错误,找不到文件
  }
}
  • package.json
{
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "bundle": "webpack"
  },
  "keywords": [],
  "author": "Boale_H",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^9.8.4",
    "css-loader": "^3.6.0",
    "file-loader": "^6.0.0",
    "less": "^3.11.3",
    "less-loader": "^6.2.0",
    "mini-css-extract-plugin": "^0.9.0",
    "node-sass": "^4.14.1",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^9.0.1",
    "style-loader": "^1.2.1",
    "url-loader": "^4.1.0",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  }
}

打包,打开index.html,发现module2没有引入index.css,也被index.css给影响到了

如何让module1.js引入的css样式只对module1.js起作用,而不影响到module2.js呢?这就需要考虑样式的模块化打包

CSS模块化打包

webpack.config.js的css-loader配置项加入modules: true 表示css模快化,即哪个js引入了样式,哪个js才会受这个样式作用,其他js不受此样式文件影响

module: {
    rules: [
      // 将css打包成单独文件
      {
        test:/\.css$/,
        use:[
            {
              loader: MiniCssExtractPlugin.loader, // mini-css-extract-plugin是将css打包成独立的文件的插件
              options: {
                publicPath: '../../' // 设置publicPath,这样css引用的背景图url就会以css所在的文件为基础
              }
            },
            {
              loader: 'css-loader', //将 CSS 转化成 CommonJS 模块
              options: {
                import: true, // 启用/禁用 @import 处理
                modules: true // 代表样式的模块化打包,即哪个js引入了样式,哪个js才会受这个样式作用,其他js不受此样式文件影响
                              // 但是这样会造成样式文件打包后,类名会变成hash值,造成样式不起作用,因此如果设置modules: true,组件中设置类名的方式则需要做调整,根据css文件类名的变化而变化
              }
            },
            'postcss-loader'  // 在css3新特性下,我们是要添加浏览器厂商前缀的。如果没有浏览器厂商前缀,同一套样式不同浏览器展现的样式是不同的。
        ]
      },
    ]
  },

但是直接这样设置,我们在打包css的时候会发现css的类名变成了哈希值,所以css样式就不起作用了

因此我们需要改变一下设置元素css类名的方法,需要用特殊方式来设置,让其动态调整,以保证组件样式类名和css文件的类名保持一致

改变一下module1.js

import style from '../assets/style/index.css';
function module1 () {
  const dom = document.getElementById('root');
  const styleShowCssOne = document.createElement('div');
  styleShowCssOne.innerText = '模块1';
  styleShowCssOne.className = style['red-font-css'];
  dom.append(styleShowCssOne);
}
export default module1;

可以看得到,引入了css的module1,样式生效了,并且没有影响到module2

文章参考

https://segmentfault.com/a/1190000022358543

https://www.w3cplus.com/css/understanding-css-modules-methodology.html

目录
相关文章
|
2月前
|
JavaScript
webpack打包TS
webpack打包TS
131 60
|
30天前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
23天前
|
前端开发 UED
Webpack 中处理 CSS 和图片资源的多 Loader 配置
【10月更文挑战第12天】 处理 CSS 和图片资源是 Webpack 配置中的重要部分。通过合理选择和配置多个 Loader,可以实现对这些资源的精细处理和优化,提升项目的性能和用户体验。在实际应用中,需要不断探索和实践,根据项目的具体情况进行灵活调整和优化,以达到最佳的处理效果。通过对 Webpack 中多 Loader 处理 CSS 和图片资源的深入了解和掌握,你将能够更好地应对各种复杂的资源处理需求,为项目的成功构建和运行提供坚实的基础。
47 1
|
30天前
|
前端开发 JavaScript
ES6模块化和webpack打包
【10月更文挑战第5天】
|
24天前
|
缓存 前端开发 JavaScript
深入了解Webpack:模块打包的革命
【10月更文挑战第11天】深入了解Webpack:模块打包的革命
|
2月前
|
JavaScript 测试技术 Windows
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
本文介绍了如何使用vue-cli和webpack为Vue项目配置不同的生产和测试环境,包括修改`package.json`脚本、使用`cross-env`处理环境变量、创建不同环境的`.env`文件,并在`webpack.prod.conf.js`中使用`DefinePlugin`来应用这些环境变量。
84 2
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
|
22天前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
24天前
|
前端开发 JavaScript 开发者
深入了解Webpack:现代JavaScript应用的打包利器
【10月更文挑战第11天】 深入了解Webpack:现代JavaScript应用的打包利器
|
2月前
|
缓存
webpack 打包多页面应用
webpack 打包多页面应用
22 1
|
2月前
webpack 打包多页面应用
webpack 打包多页面应用
下一篇
无影云桌面