当前位置:网站首页>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。
边栏推荐
- Flink实战--多流合并
- make: g++:命令未找到
- 高阶-二叉搜索树详解
- 扩散(多源广搜)
- FPGA - 7 Series FPGA internal structure clocking-01-clock Architecture Overview
- Pit of kotlin bit operation (bytes[i] and 0xff error)
- Multi label lsml for essay learning records
- SOE空间分析服务器 MySQL以及PostGres的地理空间库PostGIS防注入攻击
- Tidb single machine simulation deployment production environment cluster (closed pit practice, personal test is effective)
- c# Xml帮助类
猜你喜欢

Freeswitch dial the extension number

MongoDB:一、MongoDB是什么?MongoDB的优缺点

高阶-二叉平衡树

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

three. JS summary

ONEFLOW source code parsing: automatic inference of operator signature

Geoffrey Hinton: my 50 years of in-depth study and Research on mental skills

端口扫描工具对企业有什么帮助?

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

What if the data in the cloud disk is harmonious?
随机推荐
端口扫描工具对企业有什么帮助?
One of the characteristic agricultural products that make Tiantou village, Guankou Town, Xiamen into a "sweet" village is
Oracle create user + Role
Multi label lsml for essay learning records
68 cesium code datasource loading czml
ONEFLOW source code parsing: automatic inference of operator signature
UOW of dev XPO comparison
Minio error correction code, construction and startup of distributed Minio cluster
3D printer threading: five simple solutions
Discrimination between left and right limits of derivatives and left and right derivatives
OpenGL es: (2) relationship between OpenGL es, EGL and glsl
3D打印机穿线:5种简单的解决方案
蚂蚁新村田头村变甜头村 让厦门灌口镇田头村变甜头村的特色农产品之一是
浏览器端保存数据到本地文件
Differences between in and exists in MySQL
OpenGL es: (5) basic concepts of OpenGL, the process of OpenGL es generating pictures on the screen, and OpenGL pipeline
SystemVerilog learning-06-class encapsulation
JMM详解
栈题目:解析布尔表达式
DHT11 温湿度传感器