美文网首页
【webpack4 系列之五】

【webpack4 系列之五】

作者: 技术侠 | 来源:发表于2019-03-15 19:29 被阅读0次

    Webpack4 如何处理css

    • https://github.com/hyyfrank/webpack4 branch: feature/lesson5

    • 我们需要做什么

      • 支持css的处理

      • 把css抽取成单独的css文件

      • 支持css module

      • 支持css next等新特性

      • 支持css style lint校验

      • 减少无用的css代码

      • 使用post css做些处理比如autoprefix,css-next

      • 最小化css文件

    • 需要什么loader和plugin

      loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

      • loader:

        • sass-loader: 简单说就是sass转换成css

        • postcss-loader: postcss很强大,可以这么简单理解下,css-->ast-->plugin-->xxxx,大概就是,先把css转化为抽象语法树,然后使用javascript处理,然后厉害的就是,真的啥都有个插件,只有想不到!

        • css-loader:The css-loader interprets @import and url() like import/require() and will resolve them.选项我们会用到modules, localIdentName

        • style-loader:Adds CSS to the DOM by injecting a <style> tag

      • plugin:

        • mini-css-extract-plugin:抽取css成单独文件

        • purifycss-webpack: 删除没使用的css选择器

        • stylelint-webpack-plugin:对css做lint

        • optimize-css-assets-webpack-plugin:webpack在build的过程中优化和最小化css,默认使用cssnano做预处理器,cssnano也是个postcss的plugin

    好了,废话到此为止,上代码看下就都明了,为了让代码更清晰,我们把对css的处理单独拉出来,再通过webpack-merge合到一起,下面是css的处理代码:

    抽取代码成单独文件,现在目测原来的extract-text-webpack-plugin还是能用的,如果是使用webpack4的话,也得更新extract-text-webpack-plugin的版本到^4.0.0-beta.0,下面注释掉的,大家可以加回来试试,因为webpack4推荐使用mini-css-extract-plugin,所以我们就使用这个,而且mini-css-extract-plugin不支持hmr,但是不是在开发环境,我们只放在生产环境,其实还是ok的。

    第一步:support style-loader,css-loader,sass-loader

    
    const cssDevRules=[
    
        {
    
            loader:'style-loader'
    
        },
    
        {
    
            loader:'css-loader?modules&localIdentName=[name]_[local]_[hash:base64:5]',
    
        },
    
        {
    
            loader:'sass-loader',
    
        }
    
    ];
    
    const cssProdRules=[
    
        {
    
            loader: MiniCssExtractPlugin.loader,
    
        },
    
        {
    
            loader:'css-loader?modules&localIdentName=[name]_[local]_[hash:base64:5]',
    
        },
    
        {
    
            loader:'sass-loader',
    
        }
    
    ];
    
    console.log("is prod:"+isProd);
    
    const baseConfig = {
    
        module: {
    
            rules: [
    
                {
    
                    test: /\.(css|sass|scss)$/,
    
                    use: isProd? cssProdRules:cssDevRules,
    
                    exclude: /node_modules/,
    
                },
    
            ]
    
        },
    
        plugins: [
    
        ],
    
    };
    
    

    第二步:css-next /autoprefixer support

    加上posts-loader来支持auto-prfix自动增加,同时,为了支持css-next最新的特性,现在不需要单独加,看官方文档有个postcss-preset-env,直接加了支持autoprefixer,PostCSS Preset Env 能把现代的css转化成大部分浏览器都能解析的样式,会根据浏览器的版本决定加什么样的polyfill.

    
    npm install postcss-preset-env
    
    

    简单修改下postcss.config.js

    
    module.exports = {
    
        plugins: {
    
            'postcss-import': {},
    
            'postcss-preset-env': {
    
                browsers: 'last 2 versions',
    
            },
    
            'cssnano': {},
    
        },
    
    };
    
    
    
        {
    
            loader:'postcss-loader',
    
            options: {
    
                sourceMap: true,
    
                config: {
    
                    path: __dirname + '/postcss.config.js'
    
                }
    
            },
    
        },
    
    
    
    

    第三步:add style-lint support

    加style-lint来控制代码质量,当然我只是加上而已,具体规则要自己去定,或者你可以用标准的stylelint-config-standard,对应的plugin是stylelint-config-standard

    
    const StyleCssLintPlugin = require("stylelint-webpack-plugin");
    
    const StyleLintPlugin = new StyleCssLintPlugin({
    
        configFile: '.stylelintrc',
    
        context: 'src',
    
        files: '**/*.scss',
    
        failOnError: false,
    
        quiet: false,
    
    });
    
    baseConfig.plugins=[
    
            StyleLintPlugin,
    
            MiniCssPlugin,
    
            OptimizeCSSPlugin,
    
        ];
    
    

    当然也要加个.stylelintrc文件,现在简单先用stylelint-config-standard。

    
    {
    
      "extends": "stylelint-config-standard"
    
    }
    
    

    第四步:remove unused css

    purifycss: 移除无用css,有人使用css tree shake这种术语,anyway,感觉差不多

    
    const PurifyCSSPlugin = require("purifycss-webpack");
    
    const PurifyCssPlugin = new PurifyCSSPlugin({
    
        paths: glob.sync(path.join(__dirname, '../src/index.js')),
    
        styleExtensions: ['.css', '.scss'],
    
        purifyOptions: {
    
            whitelist: ['*purify*']
    
        }
    
    });
    
    baseConfig.plugins=[
    
        MiniCssPlugin,
    
            PurifyCssPlugin,
    
            StyleLintPlugin,
    
            OptimizeCSSPlugin,
    
            // new ExtractTextPlugin("styles.css"),
    
        ];
    
    

    第五步:minimize css

    optimize-css-assets-webpack-plugin

    cssProcessor: 压缩和优化CSS 的预处理器,现在默认是 cssnano.这是一个函数,接受一个CSS和options参数,返回promise

    canPrint: {bool} 表示插件能够在console中打印信息,默认值是true

    
    const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
    
    const OptimizeCSSPlugin = new OptimizeCSSAssetsPlugin({
    
        cssProcessor: cssnano,
    
        cssProcessorOptions: {
    
            discardComments: {
    
                removeAll: true,
    
            },
    
            // Run cssnano in safe mode to avoid
    
            // potentially unsafe transformations.
    
            safe: true,
    
        },
    
        canPrint: true,
    
    });
    
    baseConfig.plugins=[
    
        MiniCssPlugin,
    
        PurifyCssPlugin,
    
        StyleLintPlugin,
    
        OptimizeCSSPlugin,
    
        // new ExtractTextPlugin("styles.css"),
    
      ];
    
    

    OK,好了,大概该做的都做完了,如果需要进一步处理,可以考虑postcss的一些plugin,甚至可以自己写点plugin,因为这是讲webpack不是postcss,所以留给你自己探索吧~

    相关文章

      网友评论

          本文标题:【webpack4 系列之五】

          本文链接:https://www.haomeiwen.com/subject/mwnrmqtx.html