# webpack4(一) webpack的核心概念

# loader

# url-loader

用来打包图片等静态资源 例如在项目中遇到如下时使用,可以将图片打包进main.js 也可以根据图片大小进行单独打包

var pic = require('./2.jpg');
//或
import pic2 from './images/test.png';
1
2
3

先安装url-loader

npm install url-loader --save-dev
1

在webpack.config.js中配置loader

module.exports = {
    //...
    module: {
        rules: [ //添加各种loader
        //...
            {
                test: /\.(jpg|png|gif)$/,//当打包时读到.jpg/.png/.gif的文件时,会走url-loader
                use: {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',//打包的图片的名字,使用此方式的话,图片名称和后缀都和源文件相同
                        outputPath:'images/',// 打包到images/路径下
                        limit: 1024// 图片大小小于限制的时候直接打包到js里,大于的话生成到images/下
                        // 其他用法和file-loader基本一样
                    }
                },
            }
            //...
        ]
    }
    //...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# file-loader

当使用自定义字体时或打包图片时使用

先安装file-loader

npm install file-loader --save-dev
1

在webpack.config.js中配置loader

module.exports = {
    //...
    module: {
        rules: [ //添加各种loader
        //...
            {
			test: /\.(eot|ttf|svg)$/,//可以用来打包字体等文件,也可以用来打包图片
			use: {
				loader: 'file-loader'
			    } 
            }
            //...
        ]
    }
    //...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# css-loader

避免引入全局的样式,在js中分模块引入样式

import './index.css'
import './index.less'
1
2

先安装css-loader style-loader less-loader postcss-loader,用来打包加载进来的css样式

css-loader用来解析成样式 style-loader用来把样式挂在html上 postcss-loader是自动生成css兼容性前缀

npm install style-loader css-loader less-loader less postcss-loader --save-dev
1

在根目录添加 postcss.config.js,配置postcss-loader

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}
1
2
3
4
5

在webpack.config.js中配置loader

module.exports = {
    //...
    module: {
        rules: [ //添加各种loader
        //...
             {
                test: /\.css$/,
                use: [
                    //loader执行顺序从下向上
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 1,// 如果在样式文件里再import进其他的样式文件,则可能不再走下面两个loader,设置importLoaders让他重新再走一遍loader
                            //modules: true,//css模块化加载
                        }
                    },
                    'postcss-loader',//自动增加兼容性前缀
                ],
            },
             {
                test: /\.less$/,
                use: [
                    //loader执行顺序从下向上
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2,// 如果在样式文件里再import进其他的样式文件,则可能不再走下面两个loader,设置importLoaders让他重新再走一遍loader
                            //modules: true,//css模块化加载
                        }
                    },
                    'less-loader',
                    'postcss-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
38
39
40
41

# babel-loader

先安装babel-loader

npm install babel-loader @babel/core --save-dev
1

babel-loader只是将webpack和babel之间打通,但是并不能通过babel-loader将es6代码转译成es5代码,所以还需要再安装@babel/preset-env

npm install @babel/preset-env --save-dev
1

@babel/present-env也不能完全满足es6转译,像promise等语法还是原封不动的,低版本浏览器无法识别,还需要配置@babel/polyfill

npm install @babel/polyfill --save-dev
1

在webpack.config.js中配置loader

module.exports = {
    //...
    module: {
        rules: [ //添加各种loader
        //...
            {
                test: /\.js$/,
                exclude: /node_modules/,//不对node_modules下的文件进行翻译
                loader: "babel-loader",
                //babel的配置文件可以单独拿出来在根目录下的.babelrc中配置
            }
            //...
        ]
    }
    //...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

.babelrc

{
    "presets": [
        [
            "@babel/preset-env", {
                "targets": {
                    "ie": "9"// 目标能够兼容ie9以上
                },
                "useBuiltIns": "usage" // 根据文件所需要的模块进行es6转译,而不是polyfill所有的东西都打包进去
            }
        ],
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12

@babel/preset-env适用于业务代码,因为为了兼容低版本浏览器会将promise等作为全局变量注入到代码中,会造成全局污染。如果要写第三方库文件,最好使用@babel/plugin-transform-runtime

在配置中将corejs改为2后,还需要安装 @babel/runtime-core2

npm install @babel/runtime-corejs2 --save-dev
1
{
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            "corejs": 2,
            "helpers": true,
            "regenerator": true,
            "useESModules": false
        }]
    ]
}
1
2
3
4
5
6
7
8
9
10

想使用react的话要继续安装

npm install react react-dom --save-dev
1

同时为了能够让babel识别react还需要下载 @babel/preset-react

npm install @babel/preset-react --save-dev
1

在.babelrc中修改配置

{
    "presets": [
        [
            "@babel/preset-env", {
                "targets": {
                    "ie": "9"// 目标能够兼容ie9以上
                },
                "useBuiltIns": "usage" // 根据文件所需要的模块进行es6转译,而不是polyfill所有的东西都打包进去
            }
        ],
        "@babel/preset-react" // 读取的顺序是从下到上,所以react要放在下面先转译再转译成es6
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# plugin webpack插件

plugin可以在webpack运行到某个时刻帮你做些事情

# html-webpack-plugin

可以在打包的dist文件夹下自动生成html文件,同时把打包生成的js自动引入到html中

安装html-webpack-plugin

npm install html-webpack-plugin --save-dev
1

在webpack.config.js中配置

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

module.exports = {
    //...
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/index.html'// 设置一个模板html页面,使打包后的html使用模板生成,再将打包的js自动引入到html中
        }), 
    ]
    //...
}
1
2
3
4
5
6
7
8
9
10
11

# clean-webpack-plugin

可以在打包之前将目标dist文件夹清空

安装clean-webpack-plugin

npm install clean-webpack-plugin --save-dev
1

在webpack.config.js中配置

var { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    //...
    plugins: [
        new CleanWebpackPlugin(),// 每次打包之前清除文件
    ]
    //...
}
1
2
3
4
5
6
7
8
9

# entry 与 output

entry: 入口文件 output: 出口文件

entry配置项可以直接使用字符串 './src/index.js' 也可以用json来进行配置

module.exports = {
    entry: {
        "main": './src/index.js'
    },
    //或者
    // entry: './src/index.js' // 打包生成的文件默认为main.js
}
1
2
3
4
5
6
7

output

module.exports = {
    output: {
        publicPath: 'http://cdn.com.cn',//可以用来配置所以打包的js前面加上公共的地址,如cdn地址等
        filename: 'bundle.js',//打包后的js的名字,可以定死,也可以用占位符例如:[name].js 这样打包出来的文件名字和entry中配置的键值对的名字相同,默认下为main.js
        path: path.resolve(__dirname, '../dist') // 目标生成打包文件的地方
    },
}
1
2
3
4
5
6
7

# sourceMap

sourceMap是一种映射关系 现在知道dist目录下main.js文件96行出错,但其实是index.js的第一行出错 sourceMap的作用就是让我们知道是index的第一行出错

即sourceMap可以帮我们找到原文件中的错误信息位置

module.exports = {
    //...
    devtool: 'cheap-module-eval-source-map',// 开发环境下使用较好
    devtool: 'cheap-module-source-map',// 生产环境下使用较好
    //...
}
1
2
3
4
5
6

# webpackDevServer

webpackDevServer可以开启一个服务,让内容显示在服务上,在修改文件的时候可以自动更新,无需手动刷新即可看到更新后的内容

安装

npm install webpack-dev-server --save-dev
1

在package.json中配置一下scripts,这样我们就可以在命令行里快速启动 npm run start

{
    //...
    "scripts": {
        "start": "webpack-dev-server",
  },
    //...
}
1
2
3
4
5
6
7

在webpack.config.js中修改配置

module.exports = {
    //...
    devServer:{
        contentBase: './dist',
        port: 8080,// 服务的端口号
        open: true,// 启动服务时自动打开一个网页
    },
    //...
}
1
2
3
4
5
6
7
8
9

# Hot Module Replacement 热模块更新

当未开启HMR功能时,更新css或js文件会导致页面重新加载,使得已经绘制的东西重置 开启HMR后,即便调试css、js也会直接将样式内容改变而不重新加载页面。

在webpack.config.js中修改配置

const webpack = require('webpack');

module.exports = {
    //...
    devServer:{
        //...
        hot: true,// 热更新
    },
    //...
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ],
    //...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
更新时间: 11/8/2019, 4:51:43 PM