文章目录
一、npm
npm就是一个用来下载安装依赖的工具。
其配置文件是package.json。下面是一个例子:
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "my first webpack demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "fengli",
"license": "ISC",
"devDependencies": {
"css-loader": "^2.1.0",
"file-loader": "^3.0.1",
"style-loader": "^0.23.1",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1"
},
"dependencies": {
"lodash": "^4.17.11"
}
}
- name、version、description:是一些项目描述信息
- main:是程序入口,相当于java中的main函数那样
- scripts:里面是一些脚本。build那句表示npm run build 命令,来替代我们之前使用的webpack的 npx 打包命令。
二、webpack
webpack是一个打包工具,递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack不同于其他打包工具(如gulp等),它还可以打包非js文件。
说道webpack,其配置文件是webpack.config.js。当然不需要配置文件也可以进行打包,只不过想进行清晰且详细的配置,还是用配置文件好一些。
下面是webpack.config.js的一个例子:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
}
};
- entry:表示webpack打包的起始位置
- output:表示打包过程产生的.js文件的输出路径。
- module:这里面有一些规矩,用于对不是
js
的文件(比如css、png等其他文件)进行打包
2.1 用webpack进行打包
项目结构:
- dist (分发代码目录):构建过程产生的代码最小化和优化后的“输出”目录。浏览器会从这个地方加载文件,所以我们的html文件要放在这里面。另外,从src打包来的文件也会被放在这个目录下,如bundle.js
- src(源代码目录):是我们编辑代码(js文件)的地方。
三、vue
四、一个npm-webpack-vue demo
在开始下面部分是,建议花个30分钟看一下 webpack基本概念
4.1 管理资源
本节参考 webpack管理资源
以前引入css、jpg等其它图片都是从html文件中的head标签里面引入的,现在我们都在js文件中引入css文件。
例子:
import _ from 'lodash';
import './style.css';//there
import Icon from './beauity.jpg';//there
function component() {
var element = document.createElement('div');
// Lodash, now imported by this script
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
element.classList.add('hello');
// 将图像添加到我们现有的 div。
var myIcon = new Image();
myIcon.src = Icon;
element.appendChild(myIcon);
return element;
}
document.body.appendChild(component());
就是下面这两句话
import './style.css';
import Icon from './beauity.jpg';
运行效果:
最后,对目录进行一些说明。
该目录中,我们把所有资源(png,jpg,js.woff……)都是放在全局目录下的。然而当你确定某些资源只用在某个组件时,可以调整目录如下:
这里我们将全局目录下的资源调整到了my-component中,这样当其他项目需要my-component
组件时,只需要将my-component目录下的资源拷贝其他项目中就行了(当然在index.js中我们要用相对路径"./")
当然,当存在共享资源的情况下,也可以将那部分共享资源提取出来放在一个目录中(如components当前目录中)
4.2 管理输出
本节参考 webpack管理输出
- 在过去,没有npm、webpack时,我们引入css,jpg等文件都是在html文件里面一一引入的。
- 在上一节中,我们将css、jpg等文件的引入都放在了js文件里面,然后html文件只需要引入js文件就行了。然而,当我的html文件想引入多个js文件呢?那岂不是webpack.config.js里面要写很多entry和output了,这显然不太好。并且当我修改 src 下的js文件名称时,
npm run build
之后dist 生成的js文件名称改变了。然而 dist 中的html代码引用的xx.bundle.js文件的名字并不会改变,这也是不科学的。
所以我们引入 HtmlWebpackPlugin 来解决这个问题。
虽然在 dist/ 文件夹我们已经有 index.html 这个文件,然而 HtmlWebpackPlugin 还是会默认生成 index.html 文件。这就是说,它会用新生成的 index.html 文件,把我们的原来的替换。然后,所有的 bundle 会自动添加到 新添加的index.html 中。
也就是,只要在第一次编写html文件时,将依赖引入(js文件)正确之后,以后不管你怎样修改js文件的名称,在html文件中也会自动给你引入正确的bundle文件。
另外,当我js文件的名称之后,会让之前产生的bundle文件变得没有意义,然而,webpack并不会自动帮我们删除了。所以,引入clean-webpack-plugin来解决这个问题。
4.3 开发
本节参考 webpack开发
当我们有多个js文件被打包到一个bundle文件中时,当其中一个js文件里面存在错误时,那么错误会给你定位到bundle文件中。很明显,这是不科学的,我们想要它给我们定位到具体哪个js文件里面去。
因此,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。
这样,我们只需要在webpack的配置文件webpack.config.js
加一个选项 devtool: 'inline-source-map’
就行了。
每次要编译代码时,手动运行 npm run build 就会变得很麻烦。所以webpack提供了三个工具来解决这个问题。
- webpack’s Watch Mode:观察模式下,当你修改js文件后,会给你自动编译,但是需要刷新浏览器页面。
- webpack-dev-server:大多数情况下让webpack自动编译js文件,选择
webpack-dev-server
这个工具。 - webpack-dev-middleware:这是一个容器,
webpack-dev-server
内部使用的是它,用它可以进行更精细的自定义设置。
4.4 模块热替换
本节参考 webpack代码热替换
模块热替换是为了在运行时更新模块,而无需进行完全刷新。而在webpack-dev-server
模式下,需要在webpack.config.js里面配置一下在和index.js文件里面告诉 webpack 接受更新的模块就行。
然而,虽然webpack接受了新的模块,然而页面并没有重写渲染,以至于事件任然绑定在旧的函数上。此时,我们还是要从新刷新一下页面才行。这显然也是不好的。
幸好现在有很多loader
来帮我们解决类似的问题。
4.5 tree shaking
本节参考 webpack tree shaking
tree shaking 直接去掉你引入的模块文件中未用到的javascript代码。而之前那个插件clean-webpack-plugin
只是用去去掉/dist
中无用的bundle文件。
我们单纯的使用developemnt
模式的话,import {square} from './math.js’
是会这样。
这里,我们没使用的cube,它还是将cube给我们返回了。
所以,要这样才行
mode: 'development',
optimization: {
usedExports: true
},
此时再看产生的bundle文件。
现在只返回sqare了。
最后,还可以压缩产生的bundle文件,将mode改为production
就行了。
4.6 生成环境构建
本节参考 webpack生产环境构建
由于生产环境和开发环境的构建目标是不一样的。
环境 | 构建目标 |
---|---|
开发环境 | 便于开发。所以需要代码热替换,source map等功能。 |
生产环境 | 利于运行。所以需要更小的bundle文件,更轻量的source map |
因此,建议每个环境编写彼此独立的webpack 配置。
然而,我们需要一个通用设置来实现在特定环境下的代码复用。用webpack-merg可以将不同环境下的配置合并起来。
4.7 代码分离
本节参考 webpack 代码分离
代码分离是为了将代码分离到不同的bundle
文件中去,从而达到缩短加载时间的作用。常用的方法有三种。
- entry入口:使用 entry 配置手动地分离代码
- 防止重复:使用SplitChunksPlugin 去重和分离 chunk。
- 动态导入:通过模块的内联函数调用来分离代码。
entry入口这种方法不够好,还是会重复引入一些代码。
五、参考文档
webpack起步
webpack概念
webpack管理资源
webpack管理输出
webpack开发
webpack代码热替换
webpack tree shaking
webpack生产环境构建
webpack 代码分离