Skip to content

Webpack 3.x 学习-第四天 #8

@shushu2013

Description

@shushu2013

Webpack 学习第七步

1、Less, Sass, Stylus 解析

1.1 解析 Less 文件

参考资料:

less-loader GitHub 地址
less 官网

安装 lessless-loader


// 简写 cnpm i -D less
cnpm install --save-dev less

// 其中 less-loader 依赖 less 服务
cnpm i -D less-loader

配置 loader

大概过程是:先用 less-loaderLess 文件进行处理生成 CSS,再用 css-loader 对生成的 CSS 进行处理(如压缩),最后用 extract-text-webpack-plugin 提取 CSS 到单独的文件。

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {

    // ... 省略其他配置项
    
    module: {
        rules:[
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true
                            }
                        },{
                            loader: 'less-loader'
                        }
                    ],
                    // publicPath 的设置需根据提取的 css 存放的目录层级进行改变
                    publicPath: '../'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            // 从 js 文件中提取出来的 css 文件的名称,可设置路径
            filename: 'css/[name]-[contenthash:8].css'
        })
    ]
    
}
1.2 解析 Sass 文件

参考资料:

sass-loader GitHub 地址
sass 官方文档

安装 node-sasssass-loader

cnpm i -D node-sass

// sass-loader 依赖 node-sass 
cnpm i -D sass-loader

配置 loader,并使用 extract-text-webpack-plugin 将最后生成的 CSS 文件提取到指定目录下

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {

    // ... 省略其他配置项
    
    module: {
        rules:[
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true
                            }
                        },{
                            loader: 'sass-loader'
                        }
                    ],
                    // publicPath 的设置需根据提取的 css 存放的目录层级进行改变
                    publicPath: '../'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            // 从 js 文件中提取出来的 css 文件的名称,可设置路径
            filename: 'css/[name]-[contenthash:8].css'
        })
    ]
    
}
1.3 解析 Stylus 文件

参考资料:

stylus-loader GitHub 地址
stylus 官方文档

安装 stylusstylus-loader

cnpm i -D stylus

// stylus-loader 依赖 stylus
cnpm i -D stylus-loader

配置 loader,并使用 extract-text-webpack-plugin 将最后生成的 CSS 文件提取到指定目录下

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {

    // ... 省略其他配置项
    
    module: {
        rules:[
            {
                test: /\.styl$/,
                use: ExtractTextPlugin.extract({
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true
                            }
                        },{
                            loader: 'stylus-loader'
                        }
                    ],
                    // publicPath 的设置需根据提取的 css 存放的目录层级进行改变
                    publicPath: '../'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            // 从 js 文件中提取出来的 css 文件的名称,可设置路径
            filename: 'css/[name]-[contenthash:8].css'
        })
    ]
    
}

2、添加 CSS 前缀

参考资料:

postcss-loader GitHub 地址
postcss GitHub 地址
autoprefixer GitHub 地址

PostCSS 通过 JS 插件来扩展它的功能,配合插件使用可以检查 CSS、支持 CSS VariablesMixins 等很多功能。如搭配 autoprefixer 插件来给 CSS 自动添加浏览器前缀

2.1 安装 postcss-loaderautoprefixer
// postcss-loader 已经集成了 postcss ,不需要额外再安装 postcss
cnpm i -D postcss-loader autoprefixer

PostCSS 推荐在项目根目录下,建立一个 postcss.config.js 文件,配置如下

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}
2.2 设置项目要兼容的浏览器

autoprefixer 内部使用了 Browserslist 来定义你要兼容市场上哪些浏览器;
Browserslist 定义浏览器的写法参考:Browserslist GitHub 的介绍,浏览器数据来源 Can I Use
官方推荐把配置文件写入项目根目录下的 .browserslistrc 文件或在 package.jsonbrowserslist 项中配置,这里我们在 package.json 中进行配置

{

  // ... 忽略其他配置项
  
  "browserslist": [
    "> 1%",             // 兼容市场上浏览器份额大于 1% 的浏览器
    "last 2 versions",  // 兼容浏览器最新的前两个版本
    "not ie <= 8"       // 不兼容 IE8 及以下版本
  ]
  
}
2.3 在 Webpack 中配置 postcss-loader

以处理 CSS 文件为例:先用 postcss-loader 进行处理,再用 css-loader 进行处理

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {

    // ... 省略其他配置项
    
    module: {
        rules: [
            {
                // 用正则去匹配要用该 loader 转换的 CSS 文件
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    // 转换 css 文件需要使用的 Loader
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                // 在 css-loader 之前有多少个 loader 应该对 @import 资源进行解析
                                importLoaders: 1,
                                minimize: true
                            }
                        },
                        {
                            loader: 'postcss-loader'
                        }
                    ],
                    // publicPath 的设置需根据提取的 css 存放的目录层级进行改变
                    publicPath: '../'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
          // 从 js 文件中提取出来的 css 文件的名称,前面可加存放路径
          filename: `css/[name]-[contenthash:8].css`,
        })
    ]
}

处理 Less, Sass, Stylus 文件也是一样:
先用对应 Loader 处理后,再用 postcss-loader 处理,最后用 css-loader 处理

以处理 Less 文件为例

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {

    // ... 省略其他配置项
    
    module: {
        rules:[
            {
                test: /\.less$/,
                use: ExtractTextPlugin.extract({
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                // 在 css-loader 之前有多少个 loader 应该对 @import 资源进行解析
                                importLoaders: 2,
                                minimize: true
                            }
                        },
                        {
                            loader: 'postcss-loader'
                        },
                        {
                            loader: 'less-loader'
                        }
                    ],
                    // publicPath 的设置需根据提取的 css 存放的目录层级进行改变
                    publicPath: '../'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            // 从 js 文件中提取出来的 css 文件的名称,可设置路径
            filename: 'css/[name]-[contenthash:8].css'
        })
    ]
    
}

3、消除未使用的 CSS

当项目中使用到 CSS 框架(如:Bootstrap)时,很多 CSS 代码是用不到的,这就需要消除未使用的 CSS
需要使用 Webpackpurifycss-webpack 插件,其依赖 purify-css 来移除未使用的 CSS,它必须和 extract-text-webpack-plugin 插件一起使用

参考资料:

purifycss-webpack GitHub 地址
purify-css GitHub 地址

3.1 安装 purifycss-webpackpurify-css
cnpm i -D purifycss-webpack purify-css
3.2 配置 purifycss-webpack

purifycss-webpack 必须要配合 extract-text-webpack-plugin 来使用

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PurifyCssPlugin = require('purifycss-webpack');
const glob = require('glob');   // 用来同步检查 html 模板

module.exports = {

    // ... 省略其他配置项
    module: {
        rules: [
            {
                // 用正则去匹配要用该 loader 转换的 CSS 文件
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    // 转换 .css 文件需要使用的 Loader
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true
                            }
                        }
                    ],
                    // publicPath 的设置需根据提取的 css 存放的目录层级进行改变
                    publicPath: '../'
                })
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin({
            // 从 js 文件中提取出来的 css 文件的名称,可设置路径
            filename: 'css/[name]-[contenthash:8].css'
        }),
        // 确保 purifycss-plugin 在 extract-text-webpack-plugin 后面
        new PurifyCssPlugin({
            // 必须写绝对路径,同步检查 html 模板
            paths: glob.sync(path.resolve(__dirname, 'src/*.html'))
        })
    ]
    
}

Webpack 学习第八步

1、支持 ES6

1.1 babel-loader 转换 ES6

ECMAScript 6.0 是 2015 年发布的下一代 JavaScript 语言标准,它引入了新的语法和 API 来提升开发效率。

目前部分浏览器已经支持 ES6 ,但并不全面。所以在开发过程中,需要把采用 ES6 语法编写的 JS 代码转换为 ES5 语法,在 Webpack 中使用 babel-loader 来对 JS 进行转换。

参考资料:

babel-loader GitHub 地址
Babel GitHub 地址
Babel 官方文档

安装 babel-loaderbabel-core

// babel-loader 依赖 babel-core
// babel-core 是 Babel 核心
cnpm i -D babel-core babel-loader 
1.2 Babel 配置

babel-loader 通过调用 Babel 完成转换工作,我们还需对 Babel 进行配置,告诉它如何转换 JS 语法,Babel 的配置文件在项目根目录下的 .babelrc 中,格式如下:

{
    
    "plugins": [
        [
            "transform-runtime",
            {
                "polyfill": false
            }
        ]
    ],
    "presets": [
        [
            "env", 
            {
                "targets": {
                    "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
                }
            }
        ],
        "stage-2"
    ]
}

其中:

1、plugins 属性告诉 Babel 要使用哪些插件,插件可以控制如何转换代码

transform-runtime 对应的插件为 babel-plugin-transform-runtime,其作用是减少冗余代码,配合 babel-runtime 一起使用。

参考:transform-runtime 文档

2、presets 属性告诉 Babel 要对哪些语法特性进行转换,并用对应插件进行转换

env 对应的插件为 babel-preset-env,根据你支持的环境自动决定使用适合的 Babel 插件(可转换当前所有 ECMAScript 标准里的最新特性)

参考:env 文档

stage-2 对应的插件为 babel-preset-stage-2,所有使用 stage 2 (或更高)阶段的代码必备的插件 (stage 2 阶段: 是指已经被起草的特性规范,将会被纳入到标准里)

参考:stage-2 文档

Babel 配置文件中的执行顺序为:
先执行 `plugins` 再执行 `presets`
其中 `plugins` 配置顺序执行,`presets` 配置逆序执行
1.3 安装相应插件
cnpm i -D babel-plugin-transform-runtime
cnpm i -S babel-runtime

cnpm i -D babel-preset-env
cnpm i -D babel-preset-stage-2
1.4 配置 babel-laoder
module.exports = {

    // ... 省略其他配置项
    
    // 模块:例如转换 es6, less, 图片转换等...
    module: {
        rules:[
        
            // ...省略其他配置项
            
            {
                test: /\.js$/,
                use: [{
                    loader: 'babel-loader'
                }]
            }
        ]
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions