Skip to content

Latest commit

 

History

History
294 lines (274 loc) · 6.74 KB

第5章 样式处理.md

File metadata and controls

294 lines (274 loc) · 6.74 KB

第5章 样式处理

[[toc]]

分离样式文件

webpack 4之前版本是:extract-text-webpack-plugin
webpack 4及以上版本:mini-css-extract-plugin

extrach-text-webpack-plugin

const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
    module: {
        rule: [
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('bundle.css');
    ]
}

fallback属性用于指定当前插件无法提取样式时所采用的loader.

多样式文件的处理

样式的提取是以资源入口开始的整个chunk为单位的。chunk是有一组有依赖关系的模块的封装。

const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
    entry: {
        foo: './src/scripts/foo.js',
        bar: './src/scripts/bar.js'
    },
    module: {
        rule: [
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('[name].css');
    ]
}

// foo.js
// foo.css
// bar.js
// bar.css

mini-css-extract-plugin

mini-css-extract-plugin是extract-text-webpack-plugin的升级版。webpack4以后使用它进行样式的提取,4之前的版本是用不了的。

它最大的特性是支持按需加载css。a.js通过import()函数异步加载了b.js,b.js里面加载了style.js,那么使用extract-text-webpack-plugin的话,style.css最终只能被同步加载。使用mini-css-extract-plugin会单独打包出一个0.css,这个css文件将由a.js通过动态插入link标签的方式加载。

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    entry: './app.js',
    output: {
        filename: '[name].js',
    },
    mode: 'development',
    module: {
        rules: [{
            test: /\.css$/,
            use:[
                {
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        publicPath: '../',
                    }
                },
                'css-loader'
            ]
        }]
    },
    plugin: [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[id].css'
        })
    ]
}

支持配置publicPath,用来指定异步css的加载路径。
不需要设置fallback。
除了指定同步加载的css资源名filename,还需要指定异步加载的css资源名chunkFIlename。

样式预处理

sass-loader

sass-loader就是将SCSS语法编译为CSS。

npm i sass-loader node-sass
rules: [
    {
        test: /\.scss$/,
        use: ['style-loader','css-loader','sass-loader']
    }
]

假如想要在浏览器的调试工具中查看代码,需要分别为sass-loader和css-loader单独添加source map的配置项。

test: /\.scss$/,
use: [
    'style-loader',
    {
        loader: 'css-loader',
        options: {
            sourceMap: true
        }
    },
    {
        loader: 'sass-loader',
        options: {
            sourceMap: true
        }
    },
]

less

npm i less-loader less

PostCSS

PostCSS并不是一个CSS预编译器,它只是一个编译插件的平台。它的工作模式是接收样式源代码并交由编译插件处理。PostCSS 提供了一个解析器,它能够将 CSS 解析成抽象语法树(AST),我们可以通过“插件”来传递AST,然后再把AST转换成一个串,最后再输出到目标文件中去。

rules: [
    {
        test: /\.scss$/,
        use: [
            'style-loader',
            'css-loader',
            'postcss-loader'
        ]
    }
]

PostCSS要求必须有个单独的配置文件。webpack2中PostCSS不在支持从loader传入。需要在项目根目录下创建一个postcss.config.js。

// postcss.config.js
module.exports = {};

自动前缀

PostCSS最广泛的场景就是与Autoprefixer结合,为css自动添加厂商前缀。

npm i autoprefixer
// postcss.config.js
const autoprefixer = require('autoprefixer');
module.exports = {
    plugins: [
        autoprefixer({
            grid: true,
            browsers:[
                '> 1%',
                'last 3 versions',
                'android 4.2',
                'ie 8'
            ]
        })
    ]
}
.container {
    display: grid;
}

/* 编译后 */
.container {
    display: -ms-grid;
    display: grid;
}

stylelint

stylelint是一个css的质量检测工具,用来统一代码风格,确保代码质量。

npm i stylelint
// postcss.config.js
const stylelint = require('stylelint');
module.exports = {
    plugins: [
        stylelint({
            config: {
                rules: {
                    'declaration-no-important': true
                }
            }
        })
    ]
}

如果代码中出现了“!important”时就会给出警告。

CSSNext

PostCSS可以与CSSNext结合使用,让我们在应用中使用最新的CSS语法特性。

npm i postcss-cssnext
//postcss.config.css
const postcssCssnext = require('postcss-cssnext');
module.exports = {
    plugins: [
        postcssCssnext({
            // 指定所支持的浏览器
            browsers: [
                '> 1%',
                'last 2 versions'
            ]
        })
    ]
}
/* style.css */
:root {
    --highlightColor: hwb(190, 35%, 20%);
}
body {
    color: var(--highlightColor);
}

/* 打包后 */
body {
    color: rgb(89, 185, 204);
}

CSS Modules

CSS Modules就是把CSS模块化,让CSS也拥有模块的特点。使用CSS Modules不需要安装额外的模块,只需要开启css-loader中modules配置项。

module: {
    rules: [
        {
            test: /\.css/,
            use: [
                'style-loader',
                {
                    loader: 'css-loader',
                    options: {
                        modules: true,
                        localIdentName: '[name]__[local]__[hash:base64:5]',
                    }
                }
            ]
        }
    ]
}

localIdentName用于指明CSS代码中的类名会如何来编译。

/* style.css */
.title {
    color: red;
}

/* 编译后 */
.style__title__1CFy6

使用CSS Modules时CSS文件会导出一个对象:

// style.css
.title {
    color: red;
}

// app.js
import styles from './style.css';
document.write(`<h1 class="${styles.title}"></h1>`);

最终这个HTML中的class才能和编译后的CSS类名匹配上。