webpack的定义:用于现代JavaScript应用程序的静态模块打包工具。(个人理解将资源是静态的,模块化的打包成一个或多个包)webpack中文文档
webpack的打包流程
- 初始化阶段:读取webpack.config.js中的配置参数和shell命令中传入的参数进行合并并得到最终打包的参数。
- 开始编译准备阶段:启动webpack,调用webpack()方法返回一个compiler方法,创建compiler(编译器)对象并开始注册各个webpack plugin。找到配置入口中的entry代码,调用compiler.run()方法进行编译,解析项目。
- 模块编译阶段:从入口文件(entry)开始解析,调用匹配文件的loaders对文件进行处理,并找到其导入的依赖模块,递归依赖分析,行程依赖关系树。
- 完成编译阶段:在递归完成后,对不同文件类型的依赖模块文件使用对应的Loaders(模块代码转换器)进行编译,得到模块之间的相互依赖关系。
- 输出文件阶段:整理模块之间的依赖关系,同事将处理后的文件输出到output的磁盘目录中。
核心概念:
- entry(入口)
- output(输出)
- loader (模块代码转换器)
- plugin(插件)
- mode(模式)
- brower compatibility(浏览器兼容性)
- environment(环境)
入口(entry)
**入口起点(entry point)**指示webpack应该使用哪个模块,来作为构件其内部依赖图(dependency graph)的开始。进入入口起点后,webpack会找出哪些模块和库是入口起点(直接和间接)的依赖。
默认值是./src/index.js,我们可以通过在配置文件中配置entry属性,来指定一个或者多个不同的入口起点。webpack.config.js
module.export = {
ebtry:'./path/mypath/main.js'
}
-
配置单个入口(简写)语法
entry: string | [string]
module.exports = { entry:'./path/index.js' } module.exports = { entry:['./path/main.js','./path/index.js'] }
-
对象语法
entry:{<entryChunkName> string | [string]} | {}
module.exports = { entry:{ app:'./src/app.js' } } 描述入口的对象: dependOn:当前入口所依赖的入口。它们必须在入口被加载前被加载。 filename:指定要输出的文件名称。 import:启动时需加载的模块。 library:指定library选项,为当前entry构建一个library。 runtime:运行时chunk(块)的名字。如果设置了,就会创建一个新的运行时chunk。 publicPath:当该入口的输出文件在浏览器中北引用时,为它们指定一个公共URL地址。 请查看output.publicPath(https://www.webpackjs.com/configuration/output/#outputpublicpath) module.exports = { entry:{ a2:'./a', b2:{ runtime:'x2', dependOn:'a2', import:'./b' } } }
-
常见场景
分离app(应用程序)和 vendor(第三方库)入口 module.export = { entry:{ main:'./src/app.js', vendor:'./src/vendor.js' } } 多页面应用程序 module.export = { entry:{ pageOne:'./one.js', pageTwo:'./two.js' } }
输出(output)
output属性告诉webpack在哪里输出它所创建的bundle(包),以及如何命名这些文件。主要输入文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。
const path = require('path')
module.exports = {
entry:'./path/mypath/index.js',
output:{
path:path.resolve(__dirname,'dist'),
filename:'my.bundle.js'
}
}
-
用法: 在webpack配置中,output属性的最低要求是,将它的值设置为一个对象,然后为将输出文件的文件名配置为一个 output.filename
module.exports = { output:{ filename:'bundle.js' } } // 此配置将一个单独的 bundle.js 文件输出到dist 目录中
-
多个入口起点:如果配置中多于一个“chunk”,则应该使用占位符(substitutions)来确保每个文件具有唯一的名称。
module.exports = { entty:{ app:'./src/app.js', search:'./src/search.js' }, output:{ filename:'[name].js', path:__dirname + '/dist' } } // 写入到硬盘:./dist/app.js , ./dist/search.js
-
高级进阶
loader
webpack只能理解JavaScript 和JSON文件,这是webpack开箱可用的自带能力。loader让webpack能够去处理其他类型的文件,并将他们转换为有效的模块,以供应用程序使用,以及被添加到依赖图中。
在webpack的配置中,loader有两个属性:
-
test 属性,识别哪些文件会被转换
-
use 属性,定义出在进行转换时,应该使用哪个loader
const path = require('path') module.exports = { output:{ filename:'bundle.js' } module:{ rules:[{test:/\.txt$/,use:'raw-loader'}] } }
插件(plugin)
loader用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
想要使用一个插件,我们只需要require()它,然后把它添加到plugins数组中。多数插件可以通过选项(option)自定义。我们也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用new 操作符来创建一个插件实力。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack'); // 用于访问内置插件
module.exports = {
module:{
rules:[{test:/\.txt$/,use:'raw-loader'}]
},
plugins:[new HtmlWebpackPlugin({template: './src/index.html'})]
}
// html-webpack-plugin 为应用程序生成一个HTML文件,并自动将生成的所有bundle注入到此文件中
模式(mode)
通过选择 development,production或none 之中的一个,来设置mode参数,我们可以启用webpack内置在相应环境下的优化。默认值为production。
module.exports = {
mode:'production'
}
浏览器兼容性(browser compatibility)
webpack支持所有符合ES5标准的浏览器(不支持IE8及以下版本)。webpack的import()和require.ensure()需要promise。如果我们想要支持旧版本浏览器,在使用这些表达式之前,还需要提前加载polyfill。npm install --save babel-polyfill
然后使用 import 将其引入到我们的文件中。 import 'babel-polyfill'