1. webpack
webpack是基于node.js前端构建工具,就是把开发环境的代码转换为运行环境的代码,开发环境的代码是为了更好地阅读,而运行环境的代码是为了更快速的运行。两个环境的代码会有所不同,开发环境的代码经过混淆压缩,体积变的更小,而且对代码的执行也不会产生影响,这样再放在线上运行,会有更高的运行效率。通常需要构建工具处理以下几种情况:
- 代码压缩
将CSS、JS等混淆压缩,让体积变得更小 - 编译语法
编写CSS时使用的SCSS、LESS等,编写JS时使用的ES6、TypeScript等,这些是目前浏览器无法识别兼容的,因此需要构建工具去处理编译。例如使用Babel编译ES6语法。 - 模块化语法
CSS和JS模块化语法目前都无法被浏览器兼容。开发环境可以使用模块化语法,但需要构建难工具编译为浏览器可以识别的形式
其它的构建工具:最早普及使用的是Grunt,后面又出现Gulp。目前最流行的是webpack。
理解module、chunk、bundle
在webpack中,一切皆module(模块),任何一个文件都可以看作是module,js,css,图片等都是module。webpack会将入口文件以及它的依赖引入到一个chunk(块)中,然后经过一系列处理打包成bundle(包)。
chunk是代码块,bundle是打包后生成的资源文件,一个chunk可以是多个module组成的
2. 安装webpack
首先要有node环境
使用 node -v 能输出版本号即可
全局安装 webpack(不建议)
npm install -g webpack
全局安装webpack-cli
npm install -g webpack-cli
webpack -v //在全局环境中检查查找
npx webpack -v //npx帮助我们在项目的node_module里查找指定webpack
npx是npm自带的工具,帮助我们快速地启动webpack的工具。
- 报错信息1
Missing write access to /usr/local/lib/node_modules
解决方案:
是由于没有权限,在npm命令前加上sudo就可以安装了。例如sudo npm install -g webpack . 此时会提示输入密码,输入就好了,但是在屏幕命令行看不见输入的密码。
- 报错信息2
We will use “npm” to install the CLI via “npm install -D webpack-cli”.
Do you want to install ‘webpack-cli’ (yes/no): no
You need to install ‘webpack-cli’ to use webpack via CLI.
解决方案
全局安装一下sudo npm install --save-dev webpack-cli -g
3. 项目实例
新建一个项目目录,进入目录后,在终端打开,使用npm init 初始化项目,根据提示输入项目的名称、版本、描述、作者等信息。如果你不准备在npm上发布你的模块,这些信息都不重要,一路回车默认也可以。之后改目录下就会出现一个package.json文件,打开可以看到里面是刚才输入的信息。
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "webpack test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack-dev-server --config webpack.config.js"
},
"author": "kexia",
"license": "ISC",
}
安装webpack依赖,安装到devDependencies:
npm install --save-dev webpackage
这时package.json中,devDependencies中,多了webpack依赖,版本号为4.17.1
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "webpack test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack-dev-server --config webpack.config.js"
},
"author": "kexia",
"license": "ISC",
"devDependencies": {
"webpack": "^4.17.1",
}
}
安装webpack-cli依赖,安装到devDenpendencies:
npm install --save-dev webpack-cli
这时package.json中,devDependencies中,多了webpack-cli依赖
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "webpack test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack-dev-server --config webpack.config.js"
},
"author": "kexia",
"license": "ISC",
"devDependencies": {
"webpack": "^4.17.1",
"webpack-cli": "^3.3.12",
},
}
npm 安装:
- 安装时,如果没有指定版本号,则安装的为最新版本。
- npm install --save 和 npm install --save-dev的区别
–save 会把包安装到package.json的dependencies中,在发布后也会依赖
–save-dev 会把包安装到package.json的DevDenpendencie中,是开发时的依赖
在项目目录下新建src文件夹,在src下新建app.js和main.js文件。
work.js内容:
document.write('欢迎阅读webpack入门教程')
app.js内容:
var dt = require('./work.js')
在项目目录下新建index.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<div>test</div>
<script src='./dist/main.js'></script>
</body>
</html>
在命令中执行,webpack 项目入口文件地址 webpack ./src/app.js
打包成功后,项目目录下就会多一个dist文件夹,里面有main.js文件,index.html的script中引入的就是这个文件打包地址。然后把index.html运行到浏览器,可以看到运行结果。
但是如果这样使用,每次都要输入webpacke 项目入口文件地址非常麻烦。我们还可以配置webpack配置文件,webpack.config.js文件,来简化
新建webpack.config.js文件:
webpack.config.js
//webpack是基于nodeJS的,要遵循commonJS规范
const path = require('path');
const webpack = require('webpack');
module.exports = {
//上下文 项目打包的相对路径 必须是绝对路径
context:"", //默认值process.cwd(),指向当前项目的根目录,可以修改的,一般不修改
//入口 执行构建的入口 项目入口 支持三种类型的格式:字符串,数组,对象
//entry:'./src/index.js',
//entry:['./src/index.js','./src/other.js'], //不是多入口的,只有对象的格式才可以是多入口的
entry:{
//app:__dirname+'/src/app.js',//__dirname是nodejs里的一个全局变量,它指向的是我们项目的根目录
//多入口
index:'./src/index.js',
other:'./src/other.js',
},
// 出口
output:{
//构建的文件资源放在哪,必须是绝对路径
path: path.resolve(__dirname, './dist'),//是nodeJS的全局变量,返回当前目录的绝对路径__dirname打包后的文件存放的地方
//构建的的文件资源叫什么
filename:'main.js' //打包后输出文件的文件名
//多出口
//使用占位符,入口文件叫什么,占位符就替换为什么名称,无论是多出口还是单出口,都建议使用占位符
filename:'[name].js'
},
mode:'development',
module:{
rules:[
{
tets:/\.css$/, // 检查到以.css为后缀的模块时,使用下面的loader
//loader的执行顺序是从后往前
//css-loader是把css模块的内容 加入到 js模块中去,style-loader是从js中提取css的loader 在HTML中 创建style标签,放到style中。
use:["style-loader","css-loader"],
}
]
},
//插件的使用要先引入,然后new
pllugins:[
]
};
一个chunk对应一个bundle,bundle就是打包构建生成的资源文件
模块化开发 当前流行的单页面入口应用 SAP ,通过引入模块,形成依赖。
入口
执行构建的入口 项目入口 支持三种类型的格式:字符串,数组,对象
- 字符串
//entry:’./src/index.js’, - 数组
//entry:[’./src/index.js’,’./src/other.js’], //不是多入口的,只有对象的格式才可以是多入口的 - 对象
entry:{
//app:__dirname+’/src/app.js’,//__dirname是nodejs里的一个全局变量,它指向的是我们项目的根目录
//多入口
index:’./src/index.js’,
other:’./src/other.js’,
},
出口
output:{
//构建的文件资源放在哪,必须是绝对路径
path: path.resolve(__dirname, './dist'),//是nodeJS的全局变量,返回当前目录的绝对路径__dirname打包后的文件存放的地方
//单出口
// filename:'main.js' //构建的的文件资源叫什么,也就是打包后输出文件的文件名
//多出口
//使用占位符,入口文件叫什么,占位符就替换为什么名称,无论是多出口还是单出口,都建议使用占位符
filename:'[name].js'
},
占位符
- hash:整个项目的hash值,每打包一次,就会有一个新的hash值,即使代码没有改变,hash值也会变,这样浏览器的缓存就不能被利用。
- chunkhash:根据不同入口entry进行依赖解析,构建对应的chunk,生成相应的hash,只要组成entry的模块没有内容改变,则对应的hash不变。可以很好地利用缓存。
- name:入口文件的名字,字符串格式就是main;对象格式是对象的key值。
- id
组合使用: filename:’[name]-[hash:6].js’
构建模式
mode: none, production生产, development开发
生产环境会默认开启某些插件的优化
模块转换
loader:模块转换
webpack默认只支持.json和.js类型的文件 ,其它格式的模块处理,和处理方式就需要loader了。
module:{
rules:[
{
tets:/.css$/, // 检查到以.css为后缀的模块时,使用下面的loader
//loader的执行顺序是从后往前
//css-loader是把css模块的内容 加入到 js模块中去,style-loader是从js中提取css的loader 在HTML中 创建style标签,放到style中。
use:[“style-loader”,“css-loader”],
}
]
},
插件
作用于webpack打包的整个生命周期
先安装引入,然后new
pllugins:[
]
如果全局安装了webpack,则执行webpack,就会完成打包,在dist文件夹下同样会生成main.js文件(你在main.js里面设置的打包后输出的文件名是什么,在dist文件夹下生成的文件就叫什么)。
没有全局安装webpack的情况,
在package.json文件中配置start关键字。
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "webpack test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack"
},
"author": "kexia",
"license": "ISC",
"devDependencies": {
"webpack": "^4.17.1",
"webpack-cli": "^3.3.12",
},
}
执行 npm start,也可以完成打包。
如果不用start关键字,如使用dev,则要执行npm run dev.
在webpack4.0中,通过mode指定环境,用于配制运行环境。mode值可以为development表示运行模式,production表示生产模式。webpack会将production作为mode默认值去设置。
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "webpack test",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"webpack",
"dev":"webpack --mode development", //运行模式
"build":"webpack --mode production" //生产模式、线上模式
},
"author": "kexia",
"license": "ISC",
"devDependencies": {
"webpack": "^4.17.1",
"webpack-cli": "^3.3.12",
},
}
使用npm run dev,打包出来的文件大小1.12kiB; 使用npm run build,打包出来的文件大小是4.4KiB
可以看出生产模式相对于运行模式会更多地压缩体积大小。
每次修改完内容都进行打包,也挺麻烦的,我们可以实时监听文件变化并进行打包
命令行输入:
webpack --watch
webpack-dev-server 项目每次修改完之后可以自动打包并更新
postcss-loader 样式自动添加前缀,在css-loader之前使用,css3可以正常使用,不用再做兼容
autoprefixer 插件
last 2 versions 兼容最近的两个版本
1% 兼容全球浏览器的市场份额大于1%的浏览器
cdn 第一次访问有cdn快于没有cdn的,有浏览器缓存之后,就一样了。
iconfont