Skip to content

样式处理1

这一节学习如何在webpack中配置解析css模块

webpack默认只支持js模块,我们在src/目录新建一个index.css文件,随便写点样式。

css
/* webpack-dev-1\src\index.css */
body {
    background-color: red;
}

我们如果直接在index.html来引入这个文件时,比如

html
<!-- webpack-dev-1\src\index.html -->
<head>
	<!-- 在此处引用 -->
    <link rel="stylesheet" href="index.css">
</head>

我们的html-webpack-plugin并不会识别出这个引用,会原封不动的输出出去,所以链接的css文件并不会被打包到外部。所以这么做是不行的。

我们应该在js中使用require来引用它。修改之前的index.js文件,引用css样式

js
// webpack-dev-1\src\index.js
let str = require('./a.js')
console.log('hello cheny');
console.log(str);

// 引入 css 样式
require('./index.css')

这时候我们在运行一下看看 npm run dev

image-20220107155017691

报错了,说模块解析失败了,需要使用一个合适的loader来处理这个css文件。

那么什么是loader呢,它就是一个代码转换器,可以将我们的代码转换成一个模块。

css-loader、style-loader

css-loader可以帮我们处理css文件,比如css里面可以在引用其他的css,这个loader就是干这用的,把所有的css模块解析成一个js的模块

我们在src目录在建一个a.css,然后在刚才的index.css引用这个css文件

css
/* webpack-dev-1\src\a.css */
body {
    background-color: blue;
}

引入

css
/* webpack-dev-1\src\index.css */
@import './a.css'; 
body {
    background-color: red;
}

css-loader就是负责解析这种@import语法的。

当使用完css-loader解析完成css文件后,我们还需要把解析后的css文件插入到html的header标签内部,这样才能使样式生效。

所以style-loader就干了这件事。

安装一下这两个loader

shell
# css-loader style-loader -D
yarn add css-loader@2.1.1 style-loader@0.23.1 -D

修改配置文件,启用loader

js
// webpack-dev-1\webpack.config.js   
// webpack是node写出来的,所以使用node的语法

let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件

module.exports = {
    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩

    },

    mode: 'development', // 模式,默认两种模式,production 和 development

    entry: './src/index.js', // 入口

    output: {
        // 带hash戳的文件,:8限制一下hash戳的长度
        filename: 'bundle.[hash:8].js', // 打包后的文件名
        path: path.resolve(__dirname, 'build'), // 打包后的路径,必须是一个绝对路径
    },


    plugins: [ // 是一个数组,放着所有的webpack插件
        // 插件是一个类,通过new的方式来引用
        new HtmlWebpackPlugin({
            template: './src/index.html', // 告诉插件,是以这个目录下的index.html为模板
            filename: 'index.html', // 告诉插件,打包后的文件叫什么名字,这里也叫index.html
            hash: true, // 引用的时候可以加一个hash戳
        })
    ],

    module: { // 模块
        rules: [ // 规则,在这里面配置各种loader
            // css-loader 解析css文件,@import语法的
            // style-loader 把解析后的css文件 插入到head标签中
            // loader有个特点,希望单一,一个loader干一件事
            /* 
                loader的用法
                1. 只用字符串,就是只用一个loader
                2. 多个loader,需要一个数组 [],数组里可以放字符串,或者对象,对象的话就可以配置loader的参数了
            */
            // loader的顺序,默认是从右向左执行,从下往上执行
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'style-loader'
                    },
                    'css-loader'
                ]
            },
        ],
    }
}

使用npm run dev 看一下效果

image-20220107161345488

默认style-loader会把样式插入head的最后面,所以如果你自己写的样式会被覆盖掉

假如不想别覆盖掉,应该把样式插入head的最前面,可以在配置里加这个这个配置

json
{
    test: /\.css$/,
    use: [
        {
            loader: 'style-loader',
            options: {
                insertAt: 'top' // 插在顶部
            }
        },
        'css-loader'
    ]
}

less、less-loader

还可以使用less,我们在src新建一个index.less文件

css
/* webpack-dev-1\src\index.less */
body {
    div {
        border: 1px solid orange;
    }
}

在index.js中引入

js
// webpack-dev-1\src\index.js
let str = require('./a.js')

console.log('hello cheny');

console.log(str);

require('./index.css')

require('./index.less') // 引入less

修改配置文件webpack.config.js,增加less-loader

js
// webpack-dev-1\webpack.config.js
// webpack是node写出来的,所以使用node的语法

let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件

module.exports = {
    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩

    },

    mode: 'development', // 模式,默认两种模式,production 和 development

    entry: './src/index.js', // 入口

    output: {
        // 带hash戳的文件,:8限制一下hash戳的长度
        filename: 'bundle.[hash:8].js', // 打包后的文件名
        path: path.resolve(__dirname, 'build'), // 打包后的路径,必须是一个绝对路径
    },


    plugins: [ // 是一个数组,放着所有的webpack插件
        // 插件是一个类,通过new的方式来引用
        new HtmlWebpackPlugin({
            template: './src/index.html', // 告诉插件,是以这个目录下的index.html为模板
            filename: 'index.html', // 告诉插件,打包后的文件叫什么名字,这里也叫index.html
            hash: true, // 引用的时候可以加一个hash戳
        })
    ],

    module: { // 模块
        rules: [ // 规则,在这里面配置各种loader
            // css-loader 解析css文件,@import语法的
            // style-loader 把解析后的css文件 插入到head标签中
            // loader有个特点,希望单一,一个loader干一件事
            /* 
                loader的用法
                1. 只用字符串,就是只用一个loader
                2. 多个loader,需要一个数组 [],数组里可以放字符串,或者对象,对象的话就可以配置loader的参数了
            */
            // loader的顺序,默认是从右向左执行,从下往上执行
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'style-loader',
                        options: {
                            insertAt: 'top'
                        }
                    },
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    {
                        loader: 'style-loader', // 插入head标签
                        options: {
                            insertAt: 'top'
                        }
                    },
                    'css-loader', // 解析 @import语法 解析 css
                    'less-loader' // 把less 转换为 css
                ]
            },
        ],
    }
}

安装less、less-loader

shell
# less less-loader -D
yarn add less@3.9.0 less-loader@5.0.0 -D

然后重新运行一下 npm run dev,看下效果

image-20220107162857485

生效了。

同理,用sass时,就安装 sass 和 sass-loader

使用 stylus 时,就安装 stylus 和 stylus-loader

总结

webpack只能解析js模块,所以对于css需要使用loader来解析

  1. loader就是一个代码转换器,可以将我们的代码转换成一个模块。
  2. loader的解析方式是从右到左,从下到上来解析
  3. loader遵循单一功能原则,一个loader就干一个事
  4. css-loader 可以来解析 css文件,比如 @import语法
  5. style-loader 可以将解析的css文件插入到head标签里
  6. less-loader 可以将less 文件解析为css
  7. 其它的同理

参考

https://www.bilibili.com/video/BV1a4411e7Bz?p=5