当前位置:网站首页>webapck打包原理--启动过程分析
webapck打包原理--启动过程分析
2022-07-01 06:16:00 【zxuanxuanz】
一、运行命令
(1)npm script
//开发环境
npm run dev
//生产环境
npm run build(2)webpack直接执行
webpack entry.js bundle.js二、查找Webpack入口文件
(1)在命令行运行以上命令后,npm会让命令行工具进入node_modules\.bin 目目录查找是否存在 webpack.sh 或者 webpack.cmd 文件,如果存在,就执行,不存在,就抛出错误。
(2)实际的入口文件是:node_modules\webpack\bin\webpack.js
三、webpack 的入口文件:webpack.js 分析
#!/usr/bin/env node
// @ts-ignore
//正常执行返回(exitCode为0,error为null),报错会修改exitCode同时throw error
process.exitCode = 0;
/**
* @param {string} command process to run
* @param {string[]} args commandline arguments
* @returns {Promise<void>} promise
*/
//运行某个命令
//command:npm
//arg: install xxx -d
//提供一个方案快速的去执行一个命令,而不需要再命令行里手动地去输入命令
const runCommand = (command, args) => {
const cp = require("child_process");
return new Promise((resolve, reject) => {
const executedCommand = cp.spawn(command, args, {
stdio: "inherit",
shell: true
});
executedCommand.on("error", error => {
reject(error);
});
executedCommand.on("exit", code => {
if (code === 0) {
resolve();
} else {
reject();
}
});
});
};
/**
* @param {string} packageName name of the package
* @returns {boolean} is the package installed?
*/
//判断某个包是否安装
const isInstalled = packageName => {
try {
require.resolve(packageName);
return true;
} catch (err) {
return false;
}
};
/**
* @typedef {Object} CliOption
* @property {string} name display name
* @property {string} package npm package name
* @property {string} binName name of the executable file
* @property {string} alias shortcut for choice
* @property {boolean} installed currently installed?
* @property {boolean} recommended is recommended
* @property {string} url homepage
* @property {string} description description
*/
//webpack 可用的CLI:webpack-cli和webpack-command
/** @type {CliOption[]} */
const CLIs = [
//具有比较丰富的特性
{
name: "webpack-cli",
package: "webpack-cli",
binName: "webpack-cli",
alias: "cli",
installed: isInstalled("webpack-cli"),
recommended: true,
url: "https://github.com/webpack/webpack-cli",
description: "The original webpack full-featured CLI."
},
//相对来说更加轻量
{
name: "webpack-command",
package: "webpack-command",
binName: "webpack-command",
alias: "command",
installed: isInstalled("webpack-command"),
recommended: false,
url: "https://github.com/webpack-contrib/webpack-command",
description: "A lightweight, opinionated webpack CLI."
}
];
//判断两个CLI是否安装了
const installedClis = CLIs.filter(cli => cli.installed);
//一个没有安装
if (installedClis.length === 0) {
const path = require("path");
const fs = require("fs");
const readLine = require("readline");
//错误提示
let notify =
"One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:";
for (const item of CLIs) {
if (item.recommended) {
notify += `\n - ${item.name} (${item.url})\n ${item.description}`;
}
}
console.error(notify);
//提供帮助自动安装
const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
const packageManager = isYarn ? "yarn" : "npm";
const installOptions = [isYarn ? "add" : "install", "-D"];
console.error(
`We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join(
" "
)}".`
);
//询问是否安装
const question = `Do you want to install 'webpack-cli' (yes/no): `;
const questionInterface = readLine.createInterface({
input: process.stdin,
output: process.stderr
});
questionInterface.question(question, answer => {
questionInterface.close();
//是否输入yes
const normalizedAnswer = answer.toLowerCase().startsWith("y");
if (!normalizedAnswer) {
console.error(
"You need to install 'webpack-cli' to use webpack via CLI.\n" +
"You can also install the CLI manually."
);
process.exitCode = 1;
return;
}
//开始安装
const packageName = "webpack-cli";
console.log(
`Installing '${packageName}' (running '${packageManager} ${installOptions.join(
" "
)} ${packageName}')...`
);
//执行安装命令
runCommand(packageManager, installOptions.concat(packageName))
.then(() => {
require(packageName); //eslint-disable-line
})
.catch(error => {
console.error(error);
process.exitCode = 1;
});
});
//安装了一个,直接使用
} else if (installedClis.length === 1) {
const path = require("path");
const pkgPath = require.resolve(`${installedClis[0].package}/package.json`);
// eslint-disable-next-line node/no-missing-require
const pkg = require(pkgPath);
// eslint-disable-next-line node/no-missing-require
require(path.resolve(
path.dirname(pkgPath),
pkg.bin[installedClis[0].binName]
));
} else {
//安装了两个,提示要删掉一个才可以运行
console.warn(
`You have installed ${installedClis
.map(item => item.name)
.join(
" and "
)} together. To work with the "webpack" command you need only one CLI package, please remove one of them or use them directly via their binary.`
);
// @ts-ignore
process.exitCode = 1;
}
四、启动后的结果
webpack 最终找到 webpack-cli (webpack-command) 这个 npm 包,并且执行 CLI。
边栏推荐
- ABP 学习解决方案中的项目以及依赖关系
- SystemVerilog learning-07-class inheritance and package use
- One of the characteristic agricultural products that make Tiantou village, Guankou Town, Xiamen into a "sweet" village is
- SOE空间分析服务器 MySQL以及PostGres的地理空间库PostGIS防注入攻击
- The row and column numbers of each pixel of multi-source grid data in the same area are the same, that is, the number of rows and columns are the same, and the pixel size is the same
- Elements of database ER diagram
- Tidb database characteristics summary
- 【KV260】利用XADC生成芯片温度曲线图
- Treasure taking from underground palace (memory based deep search)
- Diffusion (multi-source search)
猜你喜欢

Movable mechanical wall clock

高阶-二叉搜索树详解

Ant new village is one of the special agricultural products that make Tiantou village in Guankou Town, Xiamen become Tiantou village

OpenGL es: (3) EGL, basic steps of EGL drawing, eglsurface, anativewindow

Top 10 Free 3D modeling software for beginners in 2022

PLA not pasted on the bed: 6 simple solutions
![kotlin位运算的坑(bytes[i] and 0xff 报错)](/img/2c/de0608c29d8af558f6f8dab4eb7fd8.png)
kotlin位运算的坑(bytes[i] and 0xff 报错)

数据库产生死锁了请问一下有没有解决办法

讓田頭村變甜頭村的特色農產品是仙景芋還是白菜

让厦门灌口镇田头村变“甜头”村的特色农产品之一是
随机推荐
highmap gejson数据格式转换脚本
高阶-二叉搜索树详解
OpenGL es: (1) origin of OpenGL es (transfer)
HCM Beginner (II) - information type
Thesis learning record essay multi label lift
HDU - 1501 zipper (memory deep search)
相同区域 多源栅格数据 各个像元行列号一致,即行数列数相同,像元大小相同
做技术,自信不可或缺
Make Tiantou village sweet. Is Xianjing taro or cabbage the characteristic agricultural product of Tiantou Village
SystemVerilog learning-10-validation quantification and coverage
Highmap gejson data format conversion script
How does MySQL store Emoji?
Solve the problem of garbled files uploaded by Kirin v10
Save data in browser to local file
HDU - 1501 Zipper(记忆化深搜)
Servlet
Pit of kotlin bit operation (bytes[i] and 0xff error)
【网络安全工具】USB控制软件有什么用
pycharm 配置jupyter
Oracle create user + Role