1.安装
- 全局安装webpack
- 切进当前项目目录下
- npm install -g webpack //全局
- npm install --save-dev webpack //安装到当前项目下(–save-dev 是 -D 的简写,是项目中安装的意思)
- 新建package.json
- npm init//可以自动创建这个package.json
2.根目录下创建入口文件
- index.html // 引入打包完成后的js文件,SPA应用的入口页面
- main.js // 入口js文件,会引入全部的业务场景的js
- src文件夹 // 存放页面内需要展示的业务代码
3.正式使用webpack
webpack核心概念:
- 入口(entry)
- 输出(output)
- 装饰器(loader)
- 插件(plugins)
3.1 直接在终端启用webpack进行打包
webpack ${入口js文件main.js的相对路径} -o ${打包好的js文件bundle.js的相对路径}
webpack main.js -o dist/bundle.js
3.2 利用webpack.config.js配置文件进行打包(常用)
3.2.1新建webpack.config.js文件
module.exports = {
entry: __dirname + "入口文件main.js相对路径",//入口
output:{
path: __dirname + "/dist", // 打包后输出文件的路径,该文件夹在当前目录下是不存在的
fileName: "bundle.js" // 打包后输出的js文件,该文件在当前目录下是不存在的
}
}
注意:__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
3.2.2 在package.json中定义启动webpack的打包命令
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": { //在这定义启动webpack的命令
"start": "webpack",//只有start命令可以用 npm start
"test": "echo \"Error: no test specified\" && exit 1",//其他都要用 npm run test
"dev": "webpack-dev-server --port 9999" //其他都要用 npm run dev
},
"author": "ly",
"license": "ISC",
"devDependencies": {
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
}
}
注意:package.json中的script会按一定顺序寻找命令对应位置,本地的node_modules/.bin路径就在这个寻找清单中,所以无论是全局还是局部安装的Webpack,你都不需要写前面那指明详细的路径了
3.2.3 source-map
-
正常webpack的工作流程为:代码打包压缩 -> 去空格 ->babel(后面会介绍babel的用途)编译转换
-
打包压缩编译后的项目代码和源代码之间有很大的差异,为了方便调试,定位编译后的代码的具体报错信息,我们通常用Source Maps来定位到开发中的源代码。
-
devtool:
devtool是为了在webpack中配置Source Maps,方便在控制台中找到报错信息具体出现在代码的第几行中module.exports = { devtool: 'eval-source-map', // source-map有很多种,自行百度各种区别 //__dirname 指的是当前文件所在路径 //entry后指定入口文件 entry: __dirname + "/main.js", output: { //打包后输出文件地址 path: __dirname + "/dist", filename: "bundle.js" } }
3.2.4 使用webpack构建本地服务器
-
webpack提供一个可选的本地开发服务器 webpack-dev-server
-
在webpack中进行配置之前需要单独安装它作为项目依赖
npm install --save-dev webpack-dev-servermodule.exports = { devtool: 'eval-source-map', //__dirname 指的是当前文件所在路径 //entry后指定入口文件 entry: __dirname + "/main.js", output: { //打包后输出文件地址 path: __dirname + "/dist", filename: "bundle.js" }, devServer: { // devServer 还有很多配置项,自行百度 contentBase: __dirname, //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到根目录) historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html inline: true //设置为true,当源文件改变时会自动刷新页面 } }
-
webpack.config.js中配置好后可在package.json 的script中去定义启动的命令,我这里设置了端口为9999
3.2.5 Loaders(很重要,面试常问掌握哪些loaders)
package.json结构如下
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "cross-env NODE_ENV=production webpack --config webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --progress --color --port 9999 --config webpack.config.js"
},
"author": "ly",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.3", //babel核心包
"babel-loader": "^7.1.5",//处理ES6语法
"babel-preset-env": "^1.7.0", //根据你支持的环境自动决定适合你的Babel插件
"babel-preset-es2015": "^6.24.1", //安装了上个这个其实可以不安装,再上一个里直接配置
"cross-env": "^7.0.2", //跨平台包,可以获取当前环境
"css-loader": "^3.5.2",//解析css代码,按模块打包进bundle.js中
"html-webpack-plugin": "^4.2.0",//见后文
"node-sass": "^4.13.1",// sass-loader依赖于node-sass
"sass-loader": "^8.0.2",//解析sass文件,<style lang="scss"> 这样才能正常渲染
"style-loader": "^1.1.4",//配合css-loader将解析的代码以style标签插入代码中
"vue": "^2.6.11", // 没啥说的(⊙o⊙)
"vue-loader": "^15.9.1",//解析和转换 .vue 文件
"vue-template-compiler": "^2.6.11",//vue-loader依赖vue-template-compiler
"webpack": "^4.41.6",// 没啥说的(⊙o⊙)
"webpack-cli": "^3.3.11",// 没啥说的(⊙o⊙)
"webpack-dev-server": "^3.10.3"// 本地打包调试,不会生成真正的打包文件,因为支持热部署,所以把文件都放进内存中快速更新
}
}
- 1.Loader 用来帮助webpack解析除js类型外的其他文件
- 2.Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。
- 3.Loaders需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置
- test:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
- loader:loader的名称(必须)
- include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
- query:为loaders提供额外的设置选项(可选)
- 4.介绍几个常用loader
- Babel
- Babel的作用:
- 主要用来编译js/jsx代码,支持ES6,ES7最新语法格式,不需要考虑浏览器是否支持
- Babel默认只转换新的javascript语法,而不转换新的API,比如 Iterator, Generator, Set, Maps, Proxy, Reflect,Symbol,Promise 等全局对象。以及一些在全局对象上的方法(比如 Object.assign)都不会转码
- Babel的安装与配置:e
- Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中
- 可以直接在webpack -> loaders 里进行配置
- 也可以在项目的根目录下新建一个.babelrc文件(babel转码文件),专门配置babel的各种属性,不需要特别引用,webpack通过babel进行编译时会自动从根目录下进行搜索
- 参考链接:
- Babel的作用:
- babel-polyfill
- 原理:
- 向全局对象和内置对象的prototype上添加方法来实现的。比如运行环境中不支持Array.prototype.find 方法,引入polyfill, 我们就可以使用es6方法来编写了,但是缺点就是会造成全局空间污染
- 原理:
- Babel
3.2.6 plugins
webapck.config.js结构如下
const rimraf = require('rimraf');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');
var htmlWebpackPlugin = require('html-webpack-plugin');//下面有介绍
// 删除 dist 目录
rimraf.sync('dist');
module.exports = {
mode: process.env.NODE_ENV,
devtool: 'eval-source-map',
//__dirname 指的是当前文件所在路径
//entry后指定入口文件
entry: __dirname + "/main.js",
output: {
//打包后输出文件地址
path: __dirname + "/dist",
filename: "bundle.js"
},
devServer: {
// contentBase: __dirname,
historyApiFallback: true,
inline: true,
hot: true
},
module: {
rules: [{
test: /\.(sa|sc|c)ss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}, {
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: ['env']
},
// 不去编译依赖中的js文件,优化加快速度
exclude: /node_modules/
}, {
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
scss: ['sass-loaders'],
}
}
}, ]
},
plugins: [
new VueLoaderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new htmlWebpackPlugin({
template: __dirname + '/index.html', //模板路径
filename: 'index.html' //自动生成的HTML文件的名称
})
]
}
- plugin 用来扩展webpack的功能
- 介绍几个常用plugin:
- html-webpack-plugin
- html-webpack-plugin作用:
- 1.为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
- 2.可以在打包后的文件中创建html入口文件,不配置的话打包出来只会有output处配置的js,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
- 3.这个loader如果不引用,webpack-dev-server在本地调试时,vue文件不渲染,只会渲染inde.html文件内的内容,但直接使用webpack打出的文件是可以正常渲染的,具体原因还不清楚😂
- html-webpack-plugin作用:
- mini-css-extract-plugin
- mini-css-extract-plugin作用:
- 1.从bundle.js中提取css
- 2.增加hash性能优化
- 啥是hash?关于hash性能优化参考这篇博文
- 版本迭代更新的过程中,修改某个文件,更新时不要覆盖那个文件,而是产生一个新文件
- ”_82244e91”这串字符是根据a.js的文件内容进行hash运算得到的,只有文件内容发生变化了才会有更改
- 版本迭代更新的过程中,修改某个文件,更新时不要覆盖那个文件,而是产生一个新文件
- 啥是hash?关于hash性能优化参考这篇博文
- mini-css-extract-plugin作用:
- html-webpack-plugin