webpack4使用

简介

什么是webpack?

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

为什么使用它?

如果像以前开发时一个html文件可能会引用十几个js文件,而且顺序还不能乱,因为它们存在依赖关系,同时对于ES6+等新的语法,less, sass等CSS预处理都不能很好的解决……,此时就需要一个处理这些问题的工具。

Webpack就是为处理这些问题而生的,它就是把你的项目当成一个整体,通过一个入口主文件(如:index.js),从这个文件开始找到你的项目所有的依赖文件并处理它们,最后打包成一个(或多个)浏览器可识别的JavaScript文件。

一个例子

1.初始化

首先新建一个空文件夹,用于创建项目,在终端中进入文件夹,如下我在桌面建了一个名为webpack-project的文件夹,使用终端进入文件夹后(如果对命令行不太熟悉,可参考我的博客:前端常用命令行),使用npm init命令创建一个package.json文件。

1
npm init

安装webpack

1
npm i webpack webpack-cli -D

新建文件

  1. 在目录中新建一个index.html文件
  2. 在目录中新建一个src用于存放源码,在src目录中新建一个js文件:index.js
  3. package.json中的"scripts"内写入两条命令: "dev" : "webpack --mode development""prod" : "webpack --mode production"
  4. 整体目录结构:
    1
    2
    3
    4
    5
    6
    7
    - demo
    -- node_modules
    -- src
    ---- index.js
    -- index.html
    -- package.json
    -- package-lock.json
  5. package.json中的内容:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    {
    "name": "webpackDemo",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev" : "webpack --mode development",
    "prod" : "webpack --mode production"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
    }
    }

    运行命令,会在当前根目录下生成一个dist目录,里面放着打包好的文件:
    1
    npm run dev

    入口和出口

本地服务器 webpack-dev-server

加载css

安装babel

1
npm i -D bable-loader @babel/core @babel/preset-env

生成HTML

安装插件:

1
npm i -D html-webpack-plugin

配置:

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
42
43
44
45
在webpack.config.js中配置:

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

module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'webpack.html',
minify: { // 压缩HTML文件
//是否对大小写敏感,默认false
// caseSensitive: true,
//是否简写boolean格式的属性如:disabled="disabled" 简写为disabled 默认false
collapseBooleanAttributes: true,
//是否去除空格,默认false
collapseWhitespace: true,
//是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
minifyCSS: true,
//是否压缩html里的js(使用uglify-js进行的压缩)
minifyJS: true,
//Prevents the escaping of the values of attributes
// preventAttributesEscaping: true,
//是否移除属性的引号 默认false
// removeAttributeQuotes: true,
//是否移除注释 默认false
removeComments: true,
//从脚本和样式删除的注释 默认false
// removeCommentsFromCDATA: true,
//是否删除空属性,默认false
removeEmptyAttributes: true,
// 若开启此项,生成的html中没有 body 和 head,html也未闭合
// removeOptionalTags: false,
//删除多余的属性
// removeRedundantAttributes: true,
//删除script的类型属性,在h5下面script的type默认值:text/javascript 默认值false
// removeScriptTypeAttributes: true,
//删除style的类型属性, type="text/css" 同上
// removeStyleLinkTypeAttributes: true,
//使用短的文档类型,默认false
// useShortDoctype: true,
},
hash:true
})
]
}

分离HTML中的CSS

webpacK中有两个插件可以实现这个需求

第一个插件(老版本)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 安装:
npm i -D extract-text-webpack-plugin@next
// 在webpack.config.js中配置:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
],
plugins: [new ExtractTextPlugin('./css/[name].css')]
}
}

新插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 安装
npm i -D mini-css-extract-plugin
// 在webpack.config.js中配置:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,'css-loader']
}
],
plugins: [
new MiniCssExtractPlugin({
filename:'./css/[name].css'
})
]
}
}

压缩CSS并优化结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 安装
npm i -D optimize-css-assets-webpack-plugin

// 在webpack.config.js中配置:
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = {
module: {
plugins: [
new OptimizeCssAssetsWebpackPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorPluginOptions: {
preset: ['default', {
discardComments: {
removeAll: true
}
}]
},
canPrint: true
})
]
}
}

拷贝静态文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 安装
npm i -D copy-webpack-plugin

// 在webpack.config.js中配置:
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
module: {
plugins: [
new CopyWebpackPlugin([
{
// 静态资源路径
from:__dirname+'/src/assets',
// 要打包到的路径
to:__dirname+'/dist/assets'
}
])
]
}
}

清除旧的打包文件

1
2
3
4
5
6
7
8
9
10
11
12
// 安装
npm i -D clean-webpack-plugin

// 在webpack.config.js中配置:
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
module: {
plugins: [
new CleanWebpackPlugin()
]
}
}

处理html中的内嵌图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 安装
npm i -D html-loader

module.exports = {
module: {
rules : [
test:/\.(html)$/,
use:{
loader:'html-loader',
options:{
attrs:['img:src','img:data-src']
}
}
}
]
}
}