1.下载
cnpm i -D webpack webpack-cli (-D本地开发,部署时不需要)
2.使用
webpack
默认webpack会以.src/index.js文件作为入口文中件(这里需要自己新建,所以开发中文件也都写在src目录下),打包到./dist/main.js 文件
并且默认运行环境是生产环境(会报警告未配置)
配置方法:
①可命令设置:
webpack --mode=devepolment (开发环境,打包后的main.js文件适合调试)
webpack --mode=production (生产环境)
② package.json 文件中配置: (开发中常用)
“scripts”: {
“build”: “webpack --mode=production”,
“dev” : “webpack --mode=development”
},
“scripts”: {
“dev” : “webpack --mode=development --watch” //加–watch后监听src文件改变自动执行 npm run dev
},
3.ES6和 CommonJS 导入导出区别 (webopack都支持包括混合使用)
ES6导出 导入
①export default function(){}
export default {
start(){},
stop(){}
}
important XXX from ‘./util/isPrime’ (引入名字随意,通常为引入模块名字) console.log(XXX)
② export function aaa () {}
important { aaa } from ‘./util/isPrime’
CommonJS导出 导入
module.export = { a: xxx, b:xxx }
var obj = require( ‘./util/isPrime’) conosle.log(obj.a, obj.b)
4.分析webpack导出结果(普通js代码,不会存在任何模块化的东西)
5.配置文件(默认webpack.config.js文件,必须是是有效的node代码)
配置文件中只能用CommonJS导出(Node.js代码)严格的JSON格式代码 而不能使用ES6导出
原因:” webpack 打包运行(编译)时会读取 webpack.config.js文件,分析原代码依赖关系(注意这不会执行原代码,更不会报错),形成打包结果(main.js)。可以理解为require("./ webpack.config.js"),因此必须使用CommonJs 导出
基本配置:
module.exports = {
//编译模式:一般配置文件development , run build 时 配置production,无需更改配置
mode: “development” ,
// 入口
entry: “./src/main.js”,
// 出口
output: {
filename: “bundle .js”
},
//解决打包后看不到源代码问题:
打包后的代码是有源码地图( source map),方便调试看报错(开发,生产环境都可生效)
开发环境默认"eval" 生产环境默认"none" 设置 eval-source-map 品质最佳 source map
文档地址: https://www.webpackjs.com/configuration/devtool/
devtool:“eval”,
}
6.编译过程 初始化 => 编译 => 输出
初始化:webpack会将CLI参数,配置文件,默认配置融合形成一个最终配置对象
编译:
①创建chunk(表示 通过某个入口找到所有依赖的统称) (入口真正 配置的也是这里的chunk)
根据入口文件(./src/index.js) 创建一个chunk
每个chunk有两个属性 name: main(默认), id: 唯一编号,开发环境和name相同,生产环境是数字,从0开始
②构建所有依赖关系 (通过入口模块,形成AST抽象语法树结构,递归加载模块)
AST在线测试工具: https://astexplorer.net/
第二步完成后chunk会产生一个模块列表,列表中包含了 模块id和模块转换后的代码
③产生chunk assets (资源列表 同时会生成 chunk hash : XXXX)
④如果有多个chunk 合并chunk assets ,形成一个总的资源列表,生成总的 chunk hash (出口配置的也是这里)
输出(emit):
webpack利用node中的fs模块(文件处理模块),根据编译产生总的assets,生成相应的文件
开发环境打包:
生产环境打包:
拓展: node路径相关
①"./"
1> 在模块化代码中,require("./") ,表示当前js文件所在目录
2> 在路径处理中"./“表示node运行目录
node环境中的 ‘./’
②__dirname: 所有情况下都表示当前运行的js文件所在的目录(绝对路径)
③node内置模块path
let path = require(‘path’) //导出一个对象,该对象中提供了大量路径处理的函数
let result = path.resolve(”./", “child”, “abc”, “123” ) //获取绝对路径
console.log(result) //c:\Users\Administrator\Desktop\webpack\child\abc\123 //node运行目录
let result1 = path.resolve(__dirname, “123”) //获取绝对路径
console.log(result1) // c:\Users\Administrator\Desktop\webpack\src\123
7.入口、出口配置
var path = require(“path”)
module.exports = {
// 入口 (两种写法,对象是标准写法(对象可配置多个入口))
entry: “./src/main.js”,
entry: {
main: “./src/main.js”, //默认情况 (属性名:chunk名称,属性值: 入口模块、启动模块)
a:"./src/a.js",
a:["./src/a.js", “./src/main.js”] //两个启动模块 (之后页面引入a 打包后的文件,会运行这两个启动模块的内容)
},
//静态配置出口
output: {
filename: “bundle .js”, //打包合并模块后的js文件的规则
filename: “js/bundle .js”, //规定文件夹
path: path.resolve(__dirname, ‘target’) //必须是绝对路径,表示项目打包后放置的文件夹位置, 默认是dist
},
//动态配置出口(往往多个入口文件需要配置)
output: {
filename: "[name]bundle .js", //[name]规则:会将入口chunkname动态替换
filename: "[name]-[hash]bundle .js", //[hash]规则:(hash值反应文件内容有无改变) 解决浏览器有缓存的问题
filename: "[name]-[hash:5]bundle .js", //[hash:5]: hash取几位(5位)
filename: "[name]-[chunkhash:5]bundle .js", //[chunkhash]规则:与[hash]规则相似,好处:哪个模块变,改变哪个
filename: "[id]-[chunkhash:5]bundle .js", //[id]规则: 不推荐,生产环境chunk id为数字
path: path.resolve(__dirname, 'target') //必须是绝对路径,表示项目打包后放置的文件夹位置, 默认是dist
},
devtool:"source-map"
}
8.loader
webpack做的事情,仅仅是分析各种模块的依赖关系,然后形成资源列表,最终打包生成到指定文件中
更多功能需要借助webpack loaders 和 webpack plugins完成(也叫webpack辅助工具)
webpack loader: loader本质上是一个函数,它的作用是将某个源 码字符串转化为另一个源码字符串
demo:代码中的var 可以用中文 “变量” 书写, 打包不报错 (规则一)
webpack.config.js配置:
module.exports = {
mode: “development”,
module:{
rules:[ //模块的匹配规则
{ //规则一
test:/index.jsKaTeX parse error: Expected 'EOF', got '}' at position 384: … ] }̲, {…/, //是一个正则表达式,匹配所有模块的路径以index.js结尾
use:[’./loaders/loader1’, ‘./loaders/loader2’] //匹配到之后使用哪些加载器
},
],
// noParse://是否不要解析某个模块 (之后介绍)
css loaser / img loader
9.plugin
loader的功能是转换代码,而一些其他的操作难以使用loader完成,比如
——webpack生成文件时,多生成一个说明文件
——webpack编译启动时,控制的输出一句话表示webpack启动了
这种类似的功能需要把功能嵌入到webpack编译流程中,而这种事情的实现依托于plugin
},
}