当前位置:网站首页>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。
边栏推荐
- three. JS summary
- Using Baidu map to query national subway lines
- MySQL里记录货币
- Save data in browser to local file
- 【ManageEngine卓豪】局域网监控的作用
- SOE空间分析服务器 MySQL以及PostGres的地理空间库PostGIS防注入攻击
- 【文件系统】如何在ubi之上运行squashfs
- SystemVerilog learning-10-validation quantification and coverage
- 浅谈SIEM
- Top 10 Free 3D modeling software for beginners in 2022
猜你喜欢

Transformer le village de tiantou en un village de betteraves sucrières

【ITSM】什么是ITSM,IT部门为什么需要ITSM

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

3D printer threading: five simple solutions

【文件系统】如何在ubi之上运行squashfs

Arcserver password reset (account cannot be reset)

jdbc 数据库操作

Thesis learning record essay multi label lift

C# ManualResetEvent 类的理解

Freeswitch dial the extension number
随机推荐
Linux closes the redis process SYSTEMd+
【ITSM】什么是ITSM,IT部门为什么需要ITSM
Minio error correction code, construction and startup of distributed Minio cluster
JMM详解
Using Baidu map to query national subway lines
SystemVerilog learning-07-class inheritance and package use
[self use of advanced mathematics in postgraduate entrance examination] advanced mathematics Chapter 1 thinking map in basic stage
阶乘约数(唯一分解定理)
Although pycharm is marked with red in the run-time search path, it does not affect the execution of the program
局域网监控软件有哪些功能
Recueillir des trésors dans le palais souterrain (recherche de mémoire profonde)
可动的机械挂钟
[postgraduate entrance examination advanced mathematics Wu Zhongxiang +880 version for personal use] advanced mathematics Chapter II Basic Stage mind map
SystemVerilog learning-09-interprocess synchronization, communication and virtual methods
蚂蚁新村田头村变甜头村 让厦门灌口镇田头村变甜头村的特色农产品之一是
Kubedm builds kubenetes cluster (Personal Learning version)
2022 年面向初学者的 10 大免费 3D 建模软件
MySQL怎么存储emoji?
ABP 学习解决方案中的项目以及依赖关系
机械臂速成小指南(六):步进电机驱动器