这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
开局一张图:
事先说明一下,上图目录内容是拷贝的上一章结束时的目录内容,当然,这里已经把 node_modules 和 dist 两个目录删除了。
那么,如果我们想要给上图中相关的东西做一个打包的话,该怎么做呢?
没错,步骤如下:
-
命令行终端中执行
npm install命令,安装一下此项目中的相关依赖(安装好后,项目目录结构如果没有发生变化,可以点击刷新图标手动刷新一下(如下图所示),就能看到node_modules文件夹啦); -
执行
npm run build(上一章已经配置过”build“对应的脚本内容了哦)进行打包;
打包成功后,会在项目根目录下生成一个 dist 文件夹,里面会有一个 main.js 文件(如下图所示)。
我们将这个 main.js 引入到 index.html 中,然后在 index.html 中“右键”--“Open with Live Server”,就可以把代码跑起来啦~(可以在浏览器中按 F12 -- 点击 Console 打开控制台查看效果,如果最后出现红色的报错信息,不用管它,按 F5 刷新一下页面就好了)
下面,正式进入本章内容。
上一章讲过,我们用 webpack 进行打包时,webpack 的可执行文件会去寻找当前目录下的 src 目录下的 index.js( ./src/index.js)文件,然后将其作为入口,随后去查找依赖关系图(别着急,马上会讲到哈),查到这些文件后,再对这些文件进行编译打包。
那么,如果我们把 index.js 的名字改了,比如改成 main.js,还能正常打包吗?答案是不能。但是在真实的开发环境中,入口文件不一定就得叫 index.js 呀,也可能叫其它的名字呀,那我们是否可以通过某种方式指定“入口”的名字呢?答案是可以。
先上命令:
npx webpack --entry ./src/main.js --output-path ./build
下面对上面的命令做解释:
npx webpack:执行本地的(本项目中的)webpack命令进行打包,如果本项目中没有找到webpack的可执行文件,再去全局寻找;--entry ./src/main.js:指定入口,入口为当前目录下的src目录下的main.js文件;--output-path ./build:指定出口,出口为当前目录下的build文件夹;
好,我们执行上面的这条命令(执行前先把 src 文件夹下的 index.js 名字改成 main.js 哈,此外,我这里卸载了之前使用的 v15.4.0 版本的 node,重新安装了 v15.5.0 版本的 node,如果你在执行这条命令后出现类似报错:“Error: Can't resolve 'src\main.js' in 'D:\LearnWebpack\01_learn_webpack\02_webpack配置文件(css)'”,也可以尝试将 node 更换为更新的版本后再执行该命令)看下效果:
项目根目录下生成了 build 文件夹,里面包含了一个 main.js 文件,可见,虽然我们把 src 下的 index.js 改成了 main.js,这次还是能正常打包的。而且这次打包的位置就是命令中指定的位置:当前文件夹下的 build 文件夹下。
但是在真实的开发环境里,如果你确实要像这样指定(应用程序的入口文件、生成文件的输出位置等),肯定不需要每次都敲一遍这么长的命令啦,我们会把这个命令配置到 package.json 文件里的 scripts 这一项中。比如配置成这样(注意,这里就不需要在前面加 npx 了哈):
"scripts": {
"build": "webpack --entry ./src/main.js --output-path ./build"
}
然后,(可以先把 build 文件夹删了)再在命令行终端中执行 npm run build,依然是能成功进行打包的,如下图所示:
打包后依然会生成一个 build 文件夹,里面有一个 main.js 文件,项目目录结构如下:
可见,我们是可以直接给 webpack 命令提供一些选项,来告诉它入口文件是哪个,输出目录是哪个等等。
当然,如果你现在用 Live Server 打开了 index.html 页面,会发现 Console 页面会报错,这是因为 index.html 中引入 script 脚本时,其 src 还是 dist 文件夹下的 main.js,但现在我们打包时指定的生成文件的输出位置已经变成了 build 文件夹,所以需要将 script 元素中的 src 属性的值更改为“./build/main.js”。当然,这一行 script 元素代码不应该是写死的,而应该到时候把它注入进来,如何注入呢?我们后面再讲。
下面,我们可以再去官方文档上查阅一下关于这些选项的解释,这些选项属于 API 中命令行接口(CLI)的 Flags 部分,可以看到,webpack 提供了很多 flag,我们后面在 webpack.config.js 中对 webpack 进行配置时,也会涉及到这些 flag 的内容。
以上,讲了如何通过命令行的方式给 webpack 的打包指定入口和出口。
但是,如果我们采用这种在命令行中给命令添加选项的方式来指定入口、出口等等内容,还是显得很麻烦,而且,如果要添加的选项有很多,那整条命令就太长了,可阅读性也非常差。
因此,在真实开发中,我们采用的最多的方式是,在项目的根目录下单独建一个 webpack 的配置文件(通常名为 webpack.config.js )。webpack 通过这个配置文件读取信息时,是在 node 的环境下通过 CommonJS 的方式来读取的,所以我们在这个配置文件中需要使用 CommonJS 来导出一个对象,格式如下:
module.exports = {
}
然后就可以往这个对象里面添加相关配置啦~
那么,我们先在项目根目录下新建一个 webpack.config.js 文件,做个简单配置:
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './build')
}
}
下面对上面的配置做解释(注意,这里先讲最基本的配置,不讲比较复杂的配置,复杂的配置我们后面再回过来讲):
-
entry:入口(应用程序开始执行、webpack开始打包的地方),如果只有一个入口,就可以直接跟一个字符串; -
output:出口,一般情况下是一个对象,里面再添加属性;-
filename:要输出的文件的名字 -
path:要输出的文件的存放位置(即输出文件的目标路径,注意,==必须是绝对路径==(使用Node.js的path模块))- 如果
path设置成了相对路径,比如:
module.exports = { entry: "./src/main.js", output: { filename: "bundle.js", path: "./build" } }像这样在
webpack.config.js中配置完webpack的入口和出口,我们(可以先把之前打包后生成的build文件夹删了再做测试,同时,记得删除先前在package.json中的build脚本内容中的选项部分(即删除--entry ./src/main.js --output-path ./build,不然后面执行npm run build命令时就不会再去找webpack.config.js文件中的配置了哦))再执行npm run build,执行结果如下:可以看到,运行报错了,报错信息告知我们,当前配置的
output里面的path属性,其被提供的值 “./build” 不是一个绝对路径。因此,入口(entry)可以使用相对路径,但出口(output)的路径只能是绝对路径。而要使用绝对路径,就需要导入
node中的一个内置模块——path模块,然后通过path模块来拼接绝对路径。拼接的方式是使用path模块的resolve方法,可以向该方法传入两个参数:第一个参数为__dirname,__dirname能够获取当前文件所在的目录的绝对路径,这里即webpack.config.js文件所在目录的绝对路径;第二个参数为要拼接的相对路径。比如在本项目中的webpack.config.js文件中使用path.resolve(__dirname, './build'),就相当于获取到了D:\LearnWebpack\01_learn_webpack\02_webpack配置文件(css)\build这一绝对路径。当然,这里的./build也可以直接写成build。使用绝对路径之后,我们再来运行
npm run build命令,就可以成功打包啦~结果如下:入口是
./src/main.js,出口是./build/bundle.js,没有问题哈~所以,要记住出口路径(
output.path)必须是绝对路径哦~ - 如果
-
以上,就是关于 webpack 指定入口和出口的三种方式:
- 在命令行中执行
npx webpack命令的同时通过添加选项(flags)指定; - 在
package.json文件中设置脚本,在脚本内容中添加选项(flags)指定; - 创建
webpack的配置文件,在配置文件中指定。
当然,实际开发中我们肯定是要用第三种方式即通过编写配置文件的方式来指定入口和出口的,这样做是为了考虑后期会有很多其它的东西需要配置,方便管理。