工作目录
接下来创建 /src 目录、 /src/index.js 文件
在使用vue-cli、react-cli时都会具有一个 /src 目录,这是一个 约定的工作目录。
项目中的代码文件都存放此目录下。
当然此目录名称可以随意设置,只不过约定为 /src。
/src/index.js 文件,是一个 entry(入口) 文件。
打包器 作为一个将 开发环境代码 编译 为 可部署环境代码 的桥梁,那么就必须 至少拥有一个 entry(开发环境代码) 和一个 output(可部署环境代码)
/src/index.js 就作为这么一个 entry(入口)文件
index.js 文件名称也是约定名称。
wbepack简单配置
entry、output
既然 打包器 必须有 entry(入口) 和 output(输出) ,那么就由这两个属性开始。
webpack 中就是使用 entry 和 output 作为两者的属性名称,这两个属性都可以灵活配置。
const path = require('path')
const modules = {
// 入口文件
// 字符串形式
entry:path.join(__dirname, 'src/index.js'),
// 对象形式
// entry:{
// 'index':path.join(__dirname, 'src/index.js')
// },
// 输出文件
// 字符串形式
// output:path.join(__dirname, 'dist/[name].js')
//对象形式
output:{
// 输出文件的目录地址
path:path.join(__dirname, 'dist'),
// 输出文件名称,contenthash代表一种缓存,只有文件更改才会更新hash值,重新打包
filename: '[name]_[contenthash].js'
}
}
// 使用node.js的导出,将配置进行导出
module.exports = modules
entry :入口文件。
属性可设置为:String 、 Object 、 Array
属性值为 String :直接设置一个入口文件地址
属性值为 Object :对入口文件进行详细设置和 可以设置多个入口文件
属性值为 Array :设置多个入口文件
webpack 允许设置多个 entry(入口) 文件,打包编译出多个文件。一般用于 多页面配置
至于多页面开发配置,就不在此赘述,有兴趣的朋友可以去查阅下 参考资料,单页面程序直接设置 String 即可
output:输出文件。
属性可设置为:String 、Object
属性值为 String :直接设置一个输出文件地址
属性值为 Object :输出文件地址和文件名称详细设置
webpack在设置 output.filename 时,允许使用 [name] 保留 entry 属性设置的文件名称。
entry 为 String 时, [name] 为文件名称
entry 为 Object 时, [name] 为对象的 key
output 属性中的 [contenthash] ,是 webpack 提供的一种打包缓存的机制。 webpack 会为打包编译生成一个 hash 值。只有更改源文件后才会重新打包编译,生成新的 hash 。 缓存机制一般只会在 生产模式(production) 使用。
webpack还提供了两个属性 [hash]、[chunkhash] 设置缓存,具体区别请参考:webpack中hash、chunkhash、contenthash区别
:__dirname 属性是 Node.JS 基础库中属性,表示当前文件的绝对路径。等同于path.dirname()。
webpack.json 文件中使用了 Node.JS 基础库(require('path')) 获取文件绝对地址,更准确的保证文件目录的完整性。当然也可以只使用相对地址,不过不推荐
此时使用yarn build命令就可以执行 webpack 。 最终会在根目录创建 /dist,并在 /dist 目录下生成一个 .js 文件。
文件中就是 /src/index.js 中的内容
以上就是一个最简单的 webpack 配置,只是将 entry(入口) 文件打包编译到 output(输出)。
不过 webpack 本身是一个强大的 JavaScript应用程序
接下来做小测试,在 /src 目录中创建 index2.js ,并在 index.js 中导入
此时再进行yarn build,/dist 目录下会自动再创建一个 .js 文件,这个 .js 文件就是这次打包的输出问题。
从文件中具有 index.js 和 index2.js 内容
打包后文件会进行压缩,并且代码会多出许多 webpack 构建的代码。
代码压缩是因为 webpack 默认使用的是 生产模式(production)。
如果想要不压缩代码可以在 webpack.json 文件中添加一个 mode:'development' 属性,至于这两个属性意思下一篇再详细讲解。
这就是webpack 的强大功能之一。 webpack 在打包处理文件时,会递归的构建一个 依赖图(dependency graph) ,根据这个 依赖图 将所有使用到的 JS模块 进行打包。
如果在 index.js 将引入 index2.js 的代码注释或者删除,那么 index2.js 文件内容便不会被打包。有兴趣的朋友可以自行测试。
plugins
在前面说过,webpack 只提供了一个 核心引擎。大部分功能使用 插件化 进行管理
webpack 配置项提供了一个 plugins 属性,该属性是一个 Array 类型,用于设置 plugin。
webpack 在执行时会顺序执行 plugins 中的 plugin 。
const modules = {
plugins:[
],
}
// 使用node.js的导出,将配置进行导出
module.exports = modules
webpack 默认只是一个 JavaScript应用程序 打包器,所以不会处理CSS、Image、TypeScript等 非js模块,
webpack提供了一个 loader 属性处理 非JS模块(将非JS模块转换为JS模块), 而 plugins 则为 webpack 打包时提供其他扩展。两者结合了促成了 webpack的 插件化 ,使 webpack 可以高度扩展。至于两者的分工和不同,之后会慢慢了解。
webpack 提供了自定义 plugin 的方法,具体编写规则,有兴趣的朋友可以去参考 官网
html-webpack-plugin
众所周知,运行在浏览器根源是 HTML 文件,HTML 作为 JS 文件的承载容器,哪怕将所有业务逻辑都交给 JS(Document类型) 完成,依然需要一个 HTML 容器承载,那么就需要提供一个提供的 HTML 文件的功能
webpack 中 html-webpack-plugin 就是完成这个功能的
HTML 容器也是一个 非JS模块,那么为什么使用 plugin处理 而不使用loader呢? 我个人的理解为 HTML 的提供是作为一个 JS 容器存在,而并非要转换为 JS模块 处理
webpack社区中 以 -plugin 为单词为后缀的库,都为 plugin。而以 -loader 单词为后缀的库,都为 loader。 这也是一种约定规则。
yarn add -D [email protected]
安装之后,需要在webpack文件中进行引用
const HtmlWebpackPlugin = require('html-webpack-plugin')
const modules = {
plugins: [
new HtmlWebpackPlugin()
]
}
// 使用node.js的导出,将配置进行导出
module.exports = modules
此时执行yarn build,/dist 目录便会多出一个 HTML 文件,此 HTML 还引用此次打包的 JS 文件。
在浏览器中也可以运行此 HTML ,开发者控制台中会打印 JS 文件中的 Console 语句。
真实项目中,HTML 容器也要设置很多东西。例如: Title 、 Meta 或者 icon 等。
并且在vue-cli中,会有一个 HTML 模板文件。在此 HTML 文件添加信息,并且以此文件进行作为容器。
这些信息都是由 html-webpack-plugin 构造参数提供的。
plugins: [
new HtmlWebpackPlugin({
// HTML的标题,
// template的title优先级大于当前数据
title:'my-cli',
// 输出的html文件名称
filename:'index.html',
// 本地HTML模板文件地址
template:path.join(__dirname, 'src/index.html'),
// 引用JS文件的目录路径
publicPath:'./',
// 引用JS文件的位置
// true或者body将打包后的js脚本放入body元素下,head则将脚本放到中
// 默认为true
inject:'body',
// 加载js方式,值为defer/blocking
// 默认为blocking, 如果设置了defer,则在js引用标签上加上此属性,进行异步加载
scriptLoading:'blocking',
// 是否进行缓存,默认为true,在开发环境可以设置成false
cache:false,
// 添加mate属性
meta:{}
})
]
title:HTML 的标题,
属性可设置为: String
此属性在设置 template 属性后会失效
filename:输出的 HTML 文件名称,
属性可设置为:String
默认值为: index.html
template:本地 HTML 模板文件地址。
属性可设置为:String
使用HTML模板文件时,会将 HTML 模板文件内容原封不动的 copy。
例如下面 HTML 模板引用了jquery,打包后的 HTML 依然存在jquery。
publicPath: 引用 JS 文件的目录路径。
属性可设置为:String
例如设置路径为 ./ ,那么在 HTML 文件引用 JS 时就会为 。
此属性提供了更灵活的项目管理,可以将 HTML 文件和 JS 文件打包到不同目录。
inject: 引用编译后 JS 文件的位置。
属性可设置为:Boolean 、 head 、 body
属性值为 false :代表不引用编译后 JS 文件
属性值为 true 和 body :在 body 元素最后引用编译后 JS 文件 。推荐
属性值为 head:在 head 元素中引用编译后 JS 文件,不推荐
默认值为 true
scriptLoading:设置加载 JS 的方法
属性可设置为:blocking、defer
默认值为 blocking
具体 blocking 、defer 差别可参考defer和async的区别
cache:是否缓存 HTML 文件。
属性可设置为:Boolean
默认值为 true
开发环境(development)时可以设置为 false
meta:设置 meta 属性
在此列举了html-webpack-plugin主要部分属性, 更多属性可以在npm中查看
template 属性需要是一个本地的html路径。
clean-webpack-plugin
之前每次打包编译都会在 /dist 目录创建 .js 文件,久而久之, /dist 就会具有好多无用的文件
/dist 目录往往希望它是一个干净的目录,目录内只具有最新一次的打包生成的文件。这样就可以直接以此目录进行发布。
针对这个需求,社区有大佬开发了clean-webpack-plugin。
clean-webpack-plugin 会在每次打包编译时,清空输出目录。
这个求 --- clean-webpack-plugin
yarn add -D [email protected]
将此库直接添加到 plugins 属性即可
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new CleanWebpackPlugin()
]
此时执行yarn build /dist 目录就只剩下本地打包结果。
clean-webpack-plugin库使用时为:const { CleanWebpackPlugin } =
与html-webpack-plugin库: const HtmlWebpackPlugin = 不同。
这是因为html-webpack-plugin使用了默认导出: export default ,
而clean-webpack-plugin导出的是指定类型: CleanWebpackPlugin
默认导出方式 可以使用任意变量名称进行导入:const H = require('html-webpack-plugin')。
clean-webpack-plugin也可以从构造函数中传参进行自定义设置
new CleanWebpackPlugin({
// 是否假装删除文件
// 如果为false则代表真实删除,如果为true,则代表不删除
dry:false,
// 是否将删除日志打印到控制台 默认为false
verbose: true,
// 允许保留本次打包的文件
// true为允许,false为不允许,保留本次打包结果,也就是会删除本次打包的文件
// 默认为true
protectWebpackAssets:true,
// 每次打包之前删除匹配的文件
cleanOnceBeforeBuildPatterns:["*.html"],
// 每次打包之后删除匹配的文件
cleanAfterEveryBuildPatterns:["*.js"],
})
dry:是否假装删除文件,官方文档的描述是:Simulate the removal of files。
属性可设置为:Boolean
此属性当为 true 时,则不清空 /dist 目录;当为 false 时,会清空 /dist 目录
默认值: false
verbose:是否将删除日志打印到控制台
属性可设置为:Boolean
默认值: false
protectWebpackAssets:是否保留本次打包的文件
属性可设置为:Boolean
属性值为 false 时,本次打包文件也会被清除掉
默认值: true
cleanOnceBeforeBuildPatterns:设置打包之前删除的文件
属性可设置为:Array
此属性类似一个钩子,在打包执行之前,删除此属性匹配到的文件
默认值: ['**/*']
cleanAfterEveryBuildPatterns:设置打包之后删除的文件
属性可设置为:Array
此属性与 cleanOnceBeforeBuildPatterns 类似,触发时机是打包执行完毕后
默认值: []
使用clean-webpack-plugin时其实不需要配置属性,默认就已经足够使用。
测试 clean-webpack-plugin 时,需要每次都修改 index.js 文件数据,因为 output 设置缓存,如果不修改源文件,不会重新打包
总结
打包器将开发环境代码 编译 为可部署环境代码的 “编译器”
webpack运行在Node.JS环境中, 所以写的 webpack配置项 其实是Node.JS 。
webpack配置文件需要抛出一个模块,导出模块必须为 Object 或返回 Object 的函数
webpack只提供一个 核心引擎 ,而其它功能使用 插件化 方式管理
webpack是一个 JavaScript应用程序 ,默认只支持 JS模块 的打包,对于 非JS模块 需要使用 loader 转换为 JS模块
打包器不一定非要使用 Node.JS,也可以使用JAVA、.NET等任何一门语言
打包器其实就是 IO 操作,将entry(入口)文件数据读取并经过一系列操作最终写入到output(输出)文件
如果此篇对您有所帮助,在此求一个star。项目地址: OrcasTeam/my-cli
本文参考
webpack官网
webpack中hash、chunkhash、contenthash区别
本文依赖
package.json
{
"name": "my-cli",
"version": "1.0.0",
"main": "index.js",
"author": "mowenjinzhao
"license": "MIT",
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"html-webpack-plugin": "5.2.0",
"webpack": "5.24.0",
"webpack-cli": "4.5.0"
},
"dependencies": {
"jquery": "3.5.1"
},
"scripts": {
"start": "node",
"build": "webpack --config webpack.config.js"
}
}
webpack.config.js
const path = require('path')
const modules = {
// 入口文件
// 字符串形式
entry:path.join(__dirname, 'src/index.js'),
// 对象形式
// entry:{
// 'index':path.join(__dirname, 'src/index.js')
// },
// 输出文件
// 字符串形式
// output:path.join(__dirname, 'dist/[name].js')
//对象形式
output:{
// 输出文件的目录地址
path:path.join(__dirname, 'dist'),
// 输出文件名称,contenthash代表一种缓存,只有文件更改才会更新hash值,重新打包
filename: '[name]_[contenthash].js'
},
plugins: [
new HtmlWebpackPlugin({
// HTML的标题,
// template的title优先级大于当前数据
title: 'my-cli',
// 输出的html文件名称
filename: 'index.html',
// 本地HTML模板文件地址
template: path.join(config.root, 'src/index.html'),
// 引用JS文件的目录路径
publicPath: './',
// 引用JS文件的位置
// true或者body将打包后的js脚本放入body元素下,head则将脚本放到中
// 默认为true
inject: 'body',
// 加载js方式,值为defer/blocking
// 默认为blocking, 如果设置了defer,则在js引用标签上加上此属性,进行异步加载
scriptLoading: 'blocking',
// 是否进行缓存,默认为true,在开发环境可以设置成false
cache: false,
// 添加mate属性
meta: {}
}),
new CleanWebpackPlugin({
// 是否假装删除文件
// 如果为false则代表真实删除,如果为true,则代表不删除
dry: false,
// 是否将删除日志打印到控制台 默认为false
verbose: true,
// 允许保留本次打包的文件
// true为允许,false为不允许,保留本次打包结果,也就是会删除本次打包的文件
// 默认为true
protectWebpackAssets: true,
// 每次打包之前删除匹配的文件
cleanOnceBeforeBuildPatterns: ['**/*'],
// 每次打包之后删除匹配的文件
cleanAfterEveryBuildPatterns:["*.js"],
})
]
}
// 使用node.js的导出,将配置进行导出
module.exports = modules
亚马逊测评 www.yisuping.cn