# webpack使用笔记

# 使用

不同环境下全局安装的webpack版本可能不符合这个项目,所以还是用局部依赖(或npx webpack)。

./node_modules/.bin/webpack `input.js` `output.js`
1

# path.resolve(__dirname, './src)和path.join()

有两个知识点:

  • path.resolve()
  • __dirname

# path.resolve()

作用:将路径片段解析成绝对路径;

alt

参数:String(逗号分割)

返回值:String(绝对路径)

使用说明:

  • 从右向左解析,一旦遇到绝对路径,就不继续
    • path.resolve('/foo', '/bar', 'baz') => '/bar/baz'

# __dirname

指的是当前文件所在目录的路径

alt

如图,__dirname的值为C:\Users\GaoKai\Desktop\test

以上两个可以解决“虽然各个文件所在目录不同,但可以访问某个指定目录下的文件更方便”(可以不使用../../),如下例子:

// 修改前:
import foo from '../../../util/foo'
1
2
// 修改后:
import foo from 'util/foo'

// webpack.config.js
resolve: {
    extensions: ['.js', 'vue'],
    alias: {
        // 快捷访问入口
        'util': path.resolve(__dirname, './src/util')
    }
}
1
2
3
4
5
6
7
8
9
10
11

# path.join()

参数:String(逗号分割)

返回值:String

使用说明:

  • 从左到右解析,将所有路径片段都拼接起来
  • 每个片段之间用/链接(片段之间最多只能存在1个/
path.join('a', 'b', 'c') => 'a/b/c'
path.join('a', 'b', '/c') => 'a/b/c'

path.join('/a', 'b', '/c') => '/a/b/c'
path.join('/a', '/b', '/c') => '/a/b/c'
1
2
3
4
5

# process.env.NODE_ENV

在node环境,全局变量process表示当前node进程。其中process.env表示当前系统环境的信息。

实际上,process.env里并不存在NODE_ENV这个变量,是用户自定义的。

在node环境下,console.log(process)会得到:

alt

在浏览器环境下,console.log(process)会得到:

alt

# 设置node环境下的process.env.NODE_ENV

通过cross-env来配置环境变量(支持跨平台)

"scripts": {
    "start": "cross-env NODE_ENV=development webpack-dev-server --open --config config/webpack.config.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config config/webpack.config.prod.js"
}
1
2
3
4

这样,在node环境下,process.env.NODE_ENV就有值了。

# 设置浏览器环境下的process.env.NODE_ENV

平时我们会在项目的运行过程中去判断当前环境,比如在@/axios/config.js里配置了环境变量:

export const isDev = process.env.NODE_ENV === 'development'
1

这里的process.env.NODE_ENV指的是浏览器环境下的环境变量

和node环境一样,默认是没有NODE_ENV这个变量的。

通过DefinePlugin来配置环境变量

// webpack.base.js
module.exports = {
    plugins: [
        new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) })
    ]
}
1
2
3
4
5
6

这样,在浏览器环境下,process.env.NODE_ENV就有值了。

# webpack的配置模式mode

// webpack.config.dev.js
module.exports = {
    mode: 'development' // 或'production'
}
1
2
3
4

根据官网描述,配置mode值会自动开启某些优化配置(笔者并未达到DefinePlugin效果)

alt

# webpack中运用externals

一些类似包体积比较大的包(如:lodash),可以通过CDN的形式在index.html引入后,再通过webpack.config.js里加一个externals配置。

<!-- index.html -->
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
1
2
// webpack.config.js
module.exports = {
    externals: {
        lodash: '_'
    }
}
1
2
3
4
5
6

# “对象里的条件属性”的写法

const plugin = new HtmlWebpackPlugin({
    template: paths.appHtml,
    ...(env.isProduction
        ? {
                minify: {
                    removeComments: true,
                    collapseWhitespace: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    keepClosingSlash: true,
                    minifyJS: true,
                    minifyCSS: true,
                    minifyURLs: true
                }
            }
        : {})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 区分环境变量(待补充)

new webpack.DefinePlugin({
    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
})
1
2
3

# IE8不能使用webpack?

  • IE8不怎么兼容ES5
  • 不支持__proto__
  • 不支持default关键字

# webpack插件:style-loader和mini-css-extract-plugin的区别?

# 起因

在mrc上开发组件时,编写Demo发现:在js里import的样式没有生效。

组件脚手架:reactcomponent-templatetool (opens new window)webpack.config.js (opens new window)

<!-/demo/app.js-->
import 'antd-mobile/dist/antd-mobile.css'; // 无效
import './index.less'; // 无效
1
2
3

# 配置

webpack.config.js

const config = {
    module: {
        rules: [
            {
                test: /\.(less|css)$/,
                use: [
                    // 原始配置:无其它配置
                    // 现象:样式引入不正常
                    MiniCssPlugin.loader,
                    
                    // 改进配置:引入style-loader,移除mini-css-extract-plugin
                    // 现象:样式正常
                    {
                        loader: 'style-loader'
                    }
                    
                    // 疑问配置:
                    // 现象:样式引入不正常
                    // {
                    //     loader: 'style-loader'
                    // },
                    // MiniCssPlugin.loader,

                    {
                        loader: 'css-loader'
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'less-loader'
                    }
                ]
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

通过调研发现:脚手架目前的配置仅仅是将.css抽离,并最终未插入到页面中,导致样式未生效。

# 深入调研

style-loadermini-css-extract-plugin都可用于处理“在.js中import导入的样式文件”。

不同点:

style-loader

  • 打包机制:打包到“声明'import样式文件'的同一个.js文件”中。
  • 调用时机:页面运行js时,样式会自动插入到<style>

alt

总结:需运行.js时才插入样式,无法抽离/压缩css代码

mini-css-extract-plugin

  • 打包机制:将同一个.js里所有通过import导入的样式文件都打包到同一个.css文件

    这里css的文件名可通过plugins下实例插件时,传入配置项filename进行定义。

  • 调用时机:需结合html-webpack-plugin使用,最后会以<link>形式将样式插入到页面。

alt

总结:

  • 可以将样式.js中抽离,也可结合optimization.splitChunks.cacheGroups压缩css,并合并到一个.css上;
  • 插入样式到页面。需结合html-webpack-plugin
  • 开启HMR。需对loader进行配置hrm: true
const HtmlWebpackPlugin = require('html-webpack-plugin');

new HtmlWebpackPlugin({
    template: path.join(__dirname, '../demo/index.html'),
    filename: 'index.html',
    chunks: ['test'] // <-- 打包文件名
}),
1
2
3
4
5
6
7
更新时间: 11/21/2021, 2:45:24 AM