Webpack打包CSS

开始

把博客升级到webpack4的时候CSS打包部分各类报错,总结了一下webpack4打包CSS的部分。css

项目中涉及到的模块以下:html

名称 做用 文档
css-loader 处理import或require的CSS文件 文档
style-loader 把CSS用<style>标签处理 文档
less-loader Less转化成CSS 文档
vue-style-loader style-loader的封装,把css用<style>标签注入Html,支持SSR 文档
extract-text-webpack-plugin 抽离单独文件,暂时不支持webpack4 文档
mini-css-extract-plugin 抽取css成单独文件,支持webpack4 文档
optimize-css-assets-webpack-plugin CSS压缩 文档
postcss-loader 使用PostCSS的loader 文档

loader概念

loader是一个node模块,exports出来的是一个函数。vue

module.exports = function(source) {
  // source 为一个文件的原内容字符串(或者二进制数据)
  // do something
  return xxx;
};
复制代码

加载CSS

css-loader

先看文档介绍:node

The css-loader interprets @import and url() like import/require() and will resolve them.webpack

css-loader是一个处理import或require的css文件的loader,配合 \.css$规则。
option 配置地址git

style-loader

Adds CSS to the DOM by injecting a <style> tag.github

把css用<style>标签添加到Dom里面去。
option 配置地址web

demo

demo1地址
main.js // 入口文件npm

import './main.css';

const p = document.createElement('p');
p.innerHTML = 'this is a p tag';
document.body.append(p);
console.log('this is a test');
复制代码

main.csssegmentfault

p {
    color: red;
}

.testPrefix {
    display: flex;
    transform: all 1s;
}
复制代码

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: './main.js',
    output: {
        filename: 'output.js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                loader: [
                    'style-loader',
                    'css-loader', // 会先执行css-loader
                ],
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin(),
    ],
};
复制代码

前面说到loader是输入字符串,而后输出的函数,注意loader数组的执行顺序是反的

执行webpack-dev-server --open,能够看到效果以下:

demo1-1

把style-loader去掉:

loader: [
        // 'style-loader' 注释掉style-loader
        'css-loader',
    ],
复制代码

demo1-2
能够看到没有style-loader,样式不会添加到Dom。

预处理转化

以less为例,其余相似。

less-loader

Compiles Less to CSS.

demo

把less转化成css。
demo2地址

loader: [
    'style-loader',
    'css-loader',
    'less-loader',
],
复制代码

抽离CSS

若是你的样式文件大小较大,这会作更快提早加载,由于 CSS bundle 会跟 JS bundle 并行加载

css不会阻塞HTML解析,会阻塞DOM渲染。加载css的时候会继续解析HTML,遇到JS会加载,因此是多个请求并行加载。

extract-text-webpack-plugin

Extract text from a bundle, or bundles, into a separate file.

抽离内容成单独文件的一个loader。

报错

webpack4 使用会遇到报错: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead

须要使用beta版或者用mini-css-extract-plugin代替。
npm i extract-text-webpack-plugin@next -D

demo

demo3地址
webpack.config.js配置以下:

...
test: /\.less$/,
use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: [
        'css-loader',
        'less-loader',
    ],
}),
复制代码

demo3
css被抽离成单独的文件了。

mini-css-extract-plugin

This plugin extracts CSS into separate files.

extract-text-webpack-plugin相似。

Compared to the extract-text-webpack-plugin:

  • Async loading
  • No duplicate compilation (performance)
  • Easier to use
  • Specific to CSS

extract-text-webpack-plugin对比: 异步,无重复,易于使用,针对css

用法

...
            test: /\.less$/,
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'less-loader',
            ],
        }
    ]
},
plugins: [
    new HtmlWebpackPlugin(),
    new MiniCssExtractPlugin({
        filename: '[name].css',
    }),
],
...
复制代码

PostCSS

postcss-loader

Loader for webpack to process CSS with PostCSS

使用PostCSS的loader。
PostCSS文档

PostCSS也是把CSS解析成AST,而后经过插件来输出想要的结果。

用法

demo4地址
这里用了两个PostCSS插件autoprefixercssnano
做用分别是添加兼容prefix和压缩CSS

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
    mode: 'development',
    entry: './entry.js',
    output: {
        filename: 'main.js',
    },
    module: {
        rules: [
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader', 
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: [
                                require('autoprefixer'),
                                require('cssnano'),
                            ],
                        },
                    },
                    'less-loader',
                ],
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: '[name].css',
        }),
    ],
};

复制代码

打包出来的CSS文件:
main.css

p{color:red}.testPrefix{display:flex;-webkit-transform:all 1s;transform:all 1s}
复制代码

能够看到添加了webkit前缀和压缩效果。

Vue Cli中CSS打包

使用vue inspect > output.js输出Vue-cli中webpack默认配置:
文档
以less的规则为例子

test: /\.less$/,
...
{
    resourceQuery: /\?vue/,
    use: [
      /* config.module.rule('less').oneOf('vue').use('vue-style-loader') */
      {
        loader: 'vue-style-loader',
        options: {
          sourceMap: false,
          shadowMode: false
        }
      },
      /* config.module.rule('less').oneOf('vue').use('css-loader') */
      {
        loader: 'css-loader',
        options: {
          sourceMap: false,
          importLoaders: 2
        }
      },
      /* config.module.rule('less').oneOf('vue').use('postcss-loader') */
      {
        loader: 'postcss-loader',
        options: {
          sourceMap: false
        }
      },
      /* config.module.rule('less').oneOf('vue').use('less-loader') */
      {
        loader: 'less-loader',
        options: {
          sourceMap: false
        }
      }
    ]
  },
复制代码

loader顺序为:

  • less-loader
  • postcss-loader // 默认开启autoprefixer插件
  • css-loader
  • vue-style-loader

没有抽离CSS。

参考连接

segmentfault.com/a/119000001…
www.webpackjs.com/concepts/

相关文章
相关标签/搜索