越来越多的观点(例如)认为,直接使用 node 包及其提供的命令行接口是一个不错的选择,而不是将功能抽象到任务运行器后面。部分原因是:您无论如何都在使用 npm,npm 提供了脚本功能,为什么不直接使用它呢?但它不仅仅如此。让我们一起了解这种想法,以及如何在前端开发构建过程中完成许多最重要的任务。
在过去的六个月左右,我开始在我的项目中使用 npm 脚本。在此之前,我使用的是 Gulp,再之前是 Grunt。它们为我提供了良好的服务,并通过自动化许多我过去手动执行的操作,帮助我更快、更高效地完成工作。然而,我开始觉得我是在与工具作斗争,而不是专注于我自己的代码。
Grunt、Gulp、Broccoli、Brunch 等都需要您将任务适配到它们的范式和配置中。每个工具都有自己的语法、特性和需要学习的陷阱。这增加了代码复杂性和构建复杂性,并使您专注于修复工具而不是编写代码。
这些构建工具依赖于包装核心命令行工具的插件。这在核心工具之上创建了另一层抽象,这意味着发生不良情况的可能性更大。
以下是我多次遇到的三个问题
- 如果您想要使用的命令行工具没有相应的插件,那么您将很不幸(除非您自己编写)。
- 您尝试使用的插件包装了您想要使用的工具的旧版本。您使用的插件与核心工具的当前版本之间,功能和文档并不总是匹配的。
- 错误并不总是得到很好的处理。如果插件失败,它可能不会传递核心工具的错误,从而导致挫败感,并且您实际上不知道如何调试问题。
但是,请记住……
让我说清楚:**如果您对当前的构建系统感到满意,并且它满足了您所有的需求,那么您可以继续使用它!** 仅仅因为 npm 脚本变得越来越流行并不意味着您应该放弃它。继续专注于编写代码,而不是学习更多工具。如果您开始感觉自己在与工具作斗争,那么我建议您考虑使用 npm 脚本。
如果您决定要调查或开始使用 npm 脚本,请继续阅读!您将在本文的其余部分找到大量示例任务。此外,我还创建了 npm-build-boilerplate,其中包含所有这些任务,您可以将其用作起点。让我们开始吧!
编写 npm 脚本
我们将大部分时间花费在 `package.json` 文件中。这是我们所有依赖项和脚本都将存在的地方。以下是我样板项目中简化后的版本
{
"name": "npm-build-boilerplate",
"version": "1.0.0",
"scripts": {
...
},
"devDependencies": {
...
}
}
在继续的过程中,我们将构建我们的 `package.json` 文件。我们的脚本将进入 `scripts` 对象,我们想要使用的任何工具都将被安装并放入 `devDependencies` 对象中。
在开始之前,以下是我将在本文中参考的项目的示例结构

将 SCSS 编译为 CSS
我是一个 SCSS 的重度用户,所以这就是我将要使用的。为了将 SCSS 编译为 CSS,我转向了 node-sass。首先,我们需要安装 `node-sass`;通过在命令行中运行以下命令来执行此操作
npm install --save-dev node-sass
这将在您的当前目录中安装 `node-sass`,并将其添加到 `package.json` 中的 `devDependencies` 对象中。当其他人运行您的项目时,这尤其有用,因为他们将拥有运行项目所需的一切。安装完成后,我们可以在命令行中使用它
node-sass --output-style compressed -o dist/css src/scss
让我们分解一下此命令的作用。从最后开始,它表示:在 `src/scss` 文件夹中查找任何 SCSS 文件;将编译后的 CSS 输出(`-o` 标志)到 `dist/css`;压缩输出(使用 `--output-style` 标志,并将“compressed”作为选项)。
现在我们已经在命令行中使其工作,让我们将其移动到 npm 脚本中。在您的 `package.json` 的 `scripts` 对象中,添加如下内容
"scripts": {
"scss": "node-sass --output-style compressed -o dist/css src/scss"
}
现在,返回命令行并运行
npm run scss
您将看到与在命令行中直接运行 `node-sass` 命令相同的输出。
在本帖的剩余部分中,每当我们创建 npm 脚本时,您都可以使用类似上述的命令来运行它。
只需将 `scss` 替换为您想要运行的任务的名称。
正如您将看到的,我们使用的许多命令行工具都提供了许多选项,您可以使用这些选项来完全按照您的需要进行配置。例如,以下是 (node-sass 选项) 的列表。以下是一个不同的设置示例,展示了如何传递多个选项
"scripts": {
"scss": "node-sass --output-style nested --indent-type tab --indent-width 4 -o dist/css src/scss"
}
使用 PostCSS 为 CSS 添加前缀
现在我们已经将 Scss 编译为 CSS,我们可以使用 Autoprefixer 和 PostCSS 自动添加供应商前缀。我们可以同时安装多个模块,用空格隔开它们
npm install --save-dev postcss-cli autoprefixer
我们安装了两个模块,因为 PostCSS 本身不执行任何操作。它依赖于其他插件(如 Autoprefixer)来操作您提供的 CSS。
安装必要的工具并将其保存到 `devDependencies` 后,在您的 `scripts` 对象中添加一个新任务
"scripts": {
...
"autoprefixer": "postcss -u autoprefixer -r dist/css/*"
}
此任务表示:嘿 `postcss`,使用(`-u` 标志)`autoprefixer` 替换(`-r` 标志)`dist/css` 中的任何 `.css` 文件,并使用供应商前缀代码。就是这样!需要更改 autoprefixer 的默认浏览器支持?很容易添加到脚本中
"autoprefixer": "postcss -u autoprefixer --autoprefixer.browsers '> 5%, ie 9' -r dist/css/*"
同样,您可以使用许多选项来配置自己的构建:postcss-cli 和 autoprefixer。
检查 JavaScript 代码
在编写代码时保持标准的格式和风格对于最大程度地减少错误并提高开发人员效率非常重要。“代码检查”可以帮助我们自动执行此操作,因此让我们使用 eslint 添加 JavaScript 代码检查。
再次安装软件包;这次,让我们使用快捷方式
npm i -D eslint
这与以下命令相同
npm install --save-dev eslint
安装完成后,我们将设置一些基本规则,使用 `eslint` 对我们的代码进行检查。运行以下命令以启动向导
eslint --init
我建议选择“回答有关您的样式的问题”,并回答它提出的问题。这将在您的项目根目录中生成一个新文件,`eslint` 将根据该文件检查您的代码。
现在,让我们在 `package.json` 的 `scripts` 对象中添加一个代码检查任务
"scripts": {
...
"lint": "eslint src/js"
}
我们的代码检查任务只有 13 个字符长!它在 `src/js` 文件夹中查找任何 JavaScript 文件,并根据之前生成的配置对其进行检查。当然,您可以 使用各种选项。
压缩 JavaScript 文件
让我们开始合并和压缩我们的 JavaScript 文件,我们可以使用 uglify-js 来完成。我们首先需要安装 `uglify-js`
npm i -D uglify-js
然后,我们可以在 `package.json` 中设置我们的压缩任务
"scripts": {
...
"uglify": "mkdir -p dist/js && uglifyjs src/js/*.js -m -o dist/js/app.js"
}
npm 脚本的一大优点是,它们本质上是您想要反复运行的命令行任务的别名。这意味着您可以在脚本中直接使用标准的命令行代码!此任务使用了两个标准的命令行功能,`mkdir` 和 `&&`。
此任务的前半部分,mkdir -p dist/js
表示:创建文件夹结构(mkdir
),但仅在该文件夹不存在时创建(-p
标记)。一旦成功完成,就会运行 uglifyjs
命令。&&
允许您将多个命令链接在一起,如果前一个命令成功完成,则依次运行每个命令。
此任务的后半部分告诉 uglifyjs
从 src/js/
中的所有 JS 文件(`*.js`)开始,应用“混淆”命令(-m
标记),并将结果输出到 dist/js/app.js
。再次强调,请查看相关工具的文档以获取完整的选项列表。
让我们更新我们的 uglify
任务以创建 dist/js/app.js
的压缩版本。链接另一个 uglifyjs
命令并传递“压缩”(-c
)标记。
"scripts": {
...
"uglify": "mkdir -p dist/js && uglifyjs src/js/*.js -m -o dist/js/app.js && uglifyjs src/js/*.js -m -c -o dist/js/app.min.js"
}
压缩图片
现在让我们将注意力转向压缩图片。根据httparchive.org,互联网上排名前 1000 个 URL 的平均页面大小为 1.9mb,其中图片占了 1.1mb。提高页面速度的最佳方法之一是减小图片的大小。
npm i -D imagemin-cli
Imagemin 非常棒,因为它可以压缩大多数类型的图片,包括 GIF、JPG、PNG 和 SVG。您可以向它传递一个包含图片的文件夹,它会压缩其中的所有图片,如下所示
"scripts": {
...
"imagemin": "imagemin src/images dist/images -p",
}
此任务告诉 imagemin
查找并压缩 src/images
中的所有图片,并将它们放在 dist/images
中。传递 -p
标记是为了在可能的情况下创建“渐进式”图片。查看所有可用选项的文档。
SVG 雪碧图
围绕 SVG 的热议在过去几年有所增加,这是有充分理由的。它们在所有设备上都清晰锐利,可以使用 CSS 编辑,并且对屏幕阅读器友好。但是,SVG 编辑软件通常会留下多余且不必要的代码。幸运的是,svgo 可以通过删除所有这些代码来提供帮助(我们将在下面安装它)。
您还可以自动化组合和雪碧化 SVG 以制作单个 SVG 文件的过程(此处了解更多关于此技术的信息)。为了自动化此过程,我们可以安装svg-sprite-generator。
npm i -D svgo svg-sprite-generator
模式您现在可能已经熟悉了:安装后,在您的 package.json
scripts
对象中添加一个任务
"scripts": {
...
"icons": "svgo -f src/images/icons && mkdir -p dist/images && svg-sprite-generate -d src/images/icons -o dist/images/icons.svg"
}
请注意,icons
任务基于两个 &&
指令执行三件事。首先,我们使用 svgo
,传递一个包含 SVG 的文件夹(-f
标记);这将压缩文件夹内的所有 SVG。其次,如果 dist/images
文件夹不存在,我们将创建它(使用 mkdir -p
命令)。最后,我们使用 svg-sprite-generator
,传递一个包含 SVG 的文件夹(-d
标记)和我们希望 SVG 雪碧图输出的路径(-o
标记)。
使用 BrowserSync 启动服务器并自动注入更改
拼图的最后几块之一是BrowserSync。它可以执行一些操作:启动本地服务器,自动将更新的文件注入到任何连接的浏览器中,以及在浏览器之间同步点击和滚动。安装它并添加一个任务
npm i -D browser-sync
"scripts": {
...
"serve": "browser-sync start --server --files 'dist/css/*.css, dist/js/*.js'"
}
我们的 BrowserSync 任务使用当前路径作为默认根目录启动服务器(--server
标记)。--files
标记告诉 BrowserSync 监视 dist
文件夹中的任何 CSS 或 JS 文件;每当其中的内容发生更改时,就会自动将更改的文件注入到页面中。
您可以打开多个浏览器(甚至在不同的设备上),它们都将实时获取更新的文件更改!
组合任务
使用上面所有的任务,我们能够
- 将 SCSS 编译成 CSS 并自动添加供应商前缀
- 检查和压缩 JavaScript
- 压缩图片
- 将一个包含 SVG 的文件夹转换为单个 SVG 雪碧图
- 启动本地服务器并自动将更改注入到连接到服务器的任何浏览器中
我们不要止步于此!
组合 CSS 任务
让我们添加一个组合两个 CSS 相关任务(预处理 Sass 和运行 Autoprefixer)的任务,这样我们就不必分别运行每个任务。
"scripts": {
...
"build:css": "npm run scss && npm run autoprefixer"
}
当您运行 npm run build:css
时,它会告诉命令行运行 npm run scss
;当它成功完成时,它将(&&
)运行 npm run autoprefixer
。
就像我们的 build:css
任务一样,我们可以将 JavaScript 任务链接在一起,以便更容易运行
组合 JavaScript 任务
"scripts": {
...
"build:js": "npm run lint && npm run uglify"
}
现在,我们可以调用 npm run build:js
来一步完成 JavaScript 的检查、连接和压缩!
组合剩余的任务
我们也可以对图片任务执行相同操作,以及一个将所有构建任务组合成一个的任务
"scripts": {
...
"build:images": "npm run imagemin && npm run icons",
"build:all": "npm run build:css && npm run build:js && npm run build:images",
}
监视更改
到目前为止,我们的任务需要修改文件,然后切换回命令行并运行相应的任务。我们可以做的最有用的一件事是添加监视更改的任务,当文件更改时自动运行任务。为此,我建议使用onchange。照常安装
npm i -D onchange
让我们为 CSS 和 JavaScript 设置监视任务
"scripts": {
...
"watch:css": "onchange 'src/scss/*.scss' -- npm run build:css",
"watch:js": "onchange 'src/js/*.js' -- npm run build:js",
}
以下是这些任务的细分:onchange
期望您将要监视的文件的路径作为字符串传递。我们将传递我们的源 SCSS 和 JS 文件以进行监视。我们想要运行的命令位于 --
之后,并且它将在添加、更改或删除给定路径中的文件时运行。
让我们再添加一个监视命令来完成我们的 npm 脚本构建过程。
安装另一个包,parallelshell
npm i -D parallelshell
再次,在 scripts
对象中添加一个新任务
"scripts": {
...
"watch:all": "parallelshell 'npm run serve' 'npm run watch:css' 'npm run watch:js'"
}
parallelshell
接收多个字符串,我们将传递多个 npm run
任务来运行。
为什么使用 parallelshell
来组合多个任务而不是像以前的任务那样使用 &&
?起初,我尝试过这样做。问题在于 &&
将命令链接在一起,并在启动下一个命令之前等待每个命令成功完成。但是,由于我们正在运行 watch
命令,因此它们永远不会结束!我们将陷入无限循环中。
因此,使用 parallelshell
使我们能够同时运行多个 watch
命令。
此任务使用 npm run serve
任务启动带有 BrowserSync 的服务器。然后,它开始我们针对 CSS 和 JavaScript 文件的监视命令。每当 CSS 或 JavaScript 文件发生更改时,监视任务都会执行相应的构建任务;由于 BrowserSync 设置为监视 dist
文件夹中的更改,因此它会自动将新文件注入到连接到其 URL 的任何浏览器中。太棒了!
其他有用的任务
npm
带有许多内置任务,您可以将其挂钩。让我们再编写一个利用这些内置脚本之一的任务。
"scripts": {
...
"postinstall": "npm run watch:all"
}
postinstall
命令会在你运行命令行中的 npm install
后立即执行。这在团队协作时非常有用;当有人克隆你的项目并运行 npm install
时,我们的 watch:all
任务会立即启动。他们会自动启动服务器,打开浏览器窗口,并监控文件更改。
总结
呼!我们做到了!希望你能够学习到一些关于使用 npm 脚本作为构建流程以及命令行的知识。
以防万一你错过了,我创建了一个包含所有这些任务的 npm-build-boilerplate 项目,你可以将其用作起点。如果你有任何问题或意见,请 在 Twitter 上联系我 或在下方留言。我非常乐意提供帮助!
切换到 npm 脚本非常棒,但是如果你正在维护一个开源项目并且想要最大化贡献,请确保你的脚本也适用于非 *nix 系统。最大的跨平台难题是设置环境变量(例如 NODE_ENV)。一个处理此问题的很棒的库是 better-npm-run。
另一个问题是代码注释,以及通常保持代码的可读性和可维护性。我构建了 gulp-shelter 来结合 npm 脚本和 gulpfile 的优点,而无需重新发明轮子。
我没有使用 parallelshell,而是发现 npm-run-all 非常有用。它允许在执行任务时使用通配符,例如:
构建步骤也是如此
不错!我之前没听说过这个包。感谢你的指点!
在上面所有示例中,你是全局安装所有这些东西吗?node-sass、postcss、onchange 等?还是它们仍然是项目目录下的本地安装?
我认为对于(可能)在任务运行器中对代码进行不必要的抽象,肯定存在合理的反对意见。
你将它们安装在本地,这就是 -D 标志的作用(尽管我认为文章中的
eslint --init
命令最初使用的是全局安装的版本)。但是 NPM 脚本可以使用node_modules/.bin/
,因此你安装的任何模块都会将其可执行文件放在那里,并且你可以像全局安装一样在 NPM 脚本中引用它们。因此,当本地安装时,你仍然可以在 lint 脚本中放入eslint ...
,它在运行时仍然会使用项目本地的版本。这很棒,谢谢——我一直使用 makefile(尽管语法很糟糕),我一直觉得“任务运行器”是不必要的。
让我感到不安的是,我从未想过以这种方式使用 npm 的“脚本”作为增强版的 makefile,我现在要去认真反省一下,以找出原因:-)
你可能从未想过它,因为,为什么要想呢?如果你已经在使用 make,并且正在开发 Unix 应用程序,为什么要使用 npm 脚本而不是 make 呢?Make 已经可以完全做到这一切。
我也在使用 make 进行前端构建(包括某些特定于应用程序的部署任务)。
正如你所说,make 足以胜任这一切,但既然我无论如何都在使用 node,那么抛弃那些夸夸其谈的任务运行器(以及 make,趁现在)也没有什么坏处。
但我应该自己想到这一点,因为我的偏好是更简单的构建系统。
既然你已经将脚本放在 composer.json 文件中,是否有理由使用 npm 而不是 composer 来执行它们?
https://getcomposer.org.cn/doc/articles/scripts.md
我现在已经使用 Gulp 和 Node 约 8 个月了,在工作中添加和改进我的任务。现在我有一个非常不错的样板,在每个项目的开始时只需简单下载即可。所有内容都与我的默认任务相关联,因此我只需在我的 Atom 文本编辑器的命令行中输入“gulp”,几秒钟内它就会为我构建所有内容。无需进一步简化。它已经非常简单,我遇到的唯一“困难”都是通过运行“npm update”解决的。尽管如此,还是要为这个很棒的教程点赞!
我尽量多使用 npm 脚本。如果某个任务过于复杂,我会将其编写为 gulp 任务。如果一系列任务过于缓慢并且可以跳过而不是重复执行,我会使用 Make 来编排该序列。
这是一篇关于使用 gulp 编译 Sass 比使用 npm 脚本编译 Sass 快得多的文章
我在处理的一些项目中使用了 grunt、gulp 和 npm 脚本,目前 gulp 由于其简单性、速度和基于流的特性而成为我的最爱。我们甚至在一个项目中从 npm 脚本迁移到 gulp,因为脚本非常混乱:它们包含重复的配置,由于缺乏变量而无法简化,并且“脚本”JSON 对象看起来就像一个难看的文本块,存在不跨平台的风险,并且无法对其进行记录。
但是,是的,npm 脚本仍然是我在小型项目中的首选。在我看来,关键是要知道何时选择更强大且更易于管理的东西。否则,只需使用 npm 免费提供的功能即可。
我正在使用
:P
我一定会尝试
postinstall
。我目前使用npm start
,这是一个不错的快捷方式,也是要运行的主要脚本的指针。很棒的文章!
你的设置中没有缓存清除步骤吗?
我认为对于这篇文章的目的来说,缓存清除不是必须的;但是,如果我需要添加缓存清除功能,我会使用这个模块:https://npmjs.net.cn/package/hashmark。
我会考虑将此任务添加到文章中提到的样板中。
我确实对使用 npm 处理所有事情的想法很感兴趣(我最近停止使用 Bower,因为我使用的所有前端包现在都可以在 npm 上找到,所以为什么要使用两个包管理器呢?)但是,我也最近从 Grunt 切换到 Gulp,主要是因为我发现它为我提供了巨大的速度提升,这可能是由于 Gulp 使用流在内存中而不是在磁盘上运行连续任务的方式造成的。(在我的机器上,以前在 Grunt 上需要超过一秒的任务在 Gulp 上几乎是即时的)
我猜 Gulp 的这个优势在切换到上面描述的方法后会消失……?(据我所知,看起来每个连续的任务都会从磁盘读取然后写入磁盘)。我想知道是否可以像 Gulp 那样使用 npm 脚本,但使用管道/流?
太棒了,几天前我使用 docker 容器化 nodejs,因为 Windows 不支持通配符(例如:./js/*.js),这是我的仓库:https://github.com/andru255/learn-npm-buildtool,欢迎反馈 :)
首先,我要感谢你的文章。你描述了如何轻松地使用
npm run
来执行一些文件处理,而不是 gulp/grunt。不幸的是,这种执行流式构建系统作业的方法在更复杂的使用场景中无法实现源代码映射(如果使用了 sass/less,则非常有用)怎么样——
gulp-sourcemaps
?环境条件怎么样(不要在生产环境中生成源代码映射,或者在生产环境中最小化 js/css,永远不要在开发环境中)——
gulpIf
。其他情况也是如此,当 gulp/grunt 插件必须由更精细的函数自定义时,这些函数描述了要执行的更高级别的事情。所以我会说,替换 i.e. gulp 将是浪费时间,或者只是做和你通过在 gulp 任务中设置三个或更多模块可以做的事情完全相同的事情。如果任务运行器已经完成了,那么重复自己的意义何在?为什么我们使用代码片段或高级 IDE 而不是
nano
/pico
/notepad
?我认为这一切都是为了提高生产力。Sourcemap 和环境设置完全是我无法使用 npm 脚本的原因。如果有人有简洁的解决方案,我将不胜感激。
“min-sass”: “node-sass resources/sass/main.scss | cleancss -o public/stylesheets/main.min.css –source-map”
npm run min-sass
这是另一种完成所有构建任务的方式,但我希望在实际切换到这种方式之前,先实际检查一下它是否能提高任何性能因素或节省大量时间。
如果有人有关于性能/耗时/降低复杂度的统计数据,请分享。
对于小型项目,我绝对喜欢使用 NPM 脚本,因为有时我只需要压缩 CSS 和 JS 文件,以及使用 Webpack 打包 RiotJS、React 和 Angular。我通常在 Laravel、Express 或 Meteor 之上进行开发,这些框架已经具有一些 Sass 或 JS 的魔法。我喜欢 Meteor,因为有时很多魔法可以帮助你完成任务。一切都自动发生了。对于一些项目来说,Meteor 的魔法与让人抓狂的 Gulp 构建噩梦相比,仅仅是为了上线发布一些东西,简直是医生开的药。
还有另一件事,如果你只是想开始一个使用 Stylus(或 CSS)和 Jade(或 HTML)的项目
对于较小的项目来说,这简直是太棒了。
除此之外,我开始倾向于保持 Node 更为原生。使用 `require('child_process').exec` 或 `require('child_process').execSync`,你可以像在终端一样加载任何命令。我创建了一个小脚本,用于编译和运行 Java(以及我的测试),用于一个学校项目。设置和使用都很容易。使用 Gulp 来监视文件和 CLI,但我认为在 npm 上找到执行这些任务的东西并不困难。(仅供参考:`execSync` 用于编译,`exec` 用于运行程序/测试。当执行新的操作时,我会在正在运行的程序上调用 `runningProgram.kill('SIGKILL')`)
NPM 脚本目前开始受到关注,不是因为 npm 脚本(即 shell 命令)本身有多好,而是因为它们为所有(!) 你将使用的插件提供了共同的基础。共同的基础部分很好,让我们在此基础上构建。NPM 提供的真正独特之处在于通用(shell)接口以及以编程方式重用该接口的可能性。此外,你不再需要将你、你的狗、你的妈妈和你(技术精通的未出生的)孙子曾经使用过的每个依赖项都放在你的强大无比的 PATH 中(注意:我并不是那个使用大写字母的人)。你可以将它们保存在本地。
所以 npm 脚本:太棒了!绝妙的想法。但是如果你想要真正的控制,Node(或 Python 或 Ruby)脚本才是所有内容的核心所在。
无论如何……我的建议是:通过 npm 将内容下载到你的项目本地,创建一个名为“build-scripts”的文件夹,为你的构建任务创建 npm 脚本,这些脚本使用“build-scripts”中的 Node 脚本执行任何你想要的任务,并使用 exec/execSync 执行实际的终端命令。
……由你决定。使用任何不会浪费太多时间配置的东西。最糟糕的情况是,你最终会得到一堆指向你的 npm 脚本的 `execSync` 命令。
我最近与我的同事讨论过这个问题。我认为切换到纯 npm 脚本时失去的主要内容是“任务”的通用概念。我完全同意 Gulp/Grunt/等都具有限制性的插件系统,但它们都提供了一种非常简单的方法来创建抽象任务并将它们以逻辑/可重复的方式链接在一起。
对于具有复杂构建系统的大型应用程序,拥有一个简单且一致的方法来包装任务并将它们链接在一起是必要的,而且我认为这很容易实现。
‘mkdir’ 和 ‘rm’ 在 Windows 上不起作用,因此整个过程在那里中断。此外,更诚实地显示脚本的完整哈希值(它已经相当大了)而不是省略不相关的部分。
rimraf 和 mkdirp
这并不完全正确。如果你使用类 Unix 的 shell(例如,如果你安装了 Git for Windows 而不是 Windows 的默认命令行,你将获得 bash shell),就像许多开发人员所做的那样,那么 mkdir 和 rm 以及大多数其他常见的 Unix 命令在 Windows 上都可以正常工作。
我喜欢这个:“让我这样说:如果你对当前的构建系统感到满意,并且它完成了你需要它完成的所有事情,你可以继续使用它!”
现在太多“不要使用它,使用这个”了……
“什么时候在包清单中编写构建脚本变成‘正确’的做法了?”——Jon Schlinkert
非常感谢这篇文章!它确实帮助我在使用 `webpack` 和 `npm` 的复杂设置中处理并发任务时遇到了很多困难。
但我仍然无法弄清楚的一件事。当运行
npm 任务在成功完成之后退出。我还想监视图标任务。有没有办法做到这一点?
Katja,
看起来你需要为图标设置一个监视任务,然后用 `npm run watch:icons` 替换 `npm run icons`。
我喜欢调用 `node_modules` 文件夹内的二进制文件,而不是依赖全局命令。
而不是
我会使用
在看到上面 Stephen Sauceda 的评论后,我认为这样做更有意义
这实际上是 npm 在幕后所做的,所以你无必要地使你的 `package.json` 混乱。NPM 文档说明
它甚至进一步指出
npm 文档来源
不错!如果知道 npm 是在 PATH 变量的开头还是结尾添加内容会很好。我在文档中没有找到答案。这将决定 npm 默认使用本地安装还是全局安装,如果存在版本冲突,这将有所不同。
嘿,Damon,很棒的文章!
对于所有使用标准命令行而不是类 Unix 命令行的 Windows 用户,是否可以像这样重写 `mkdir -p` 部分
if not exist dist\\js mkdir dist\\js
Windows 斜杠需要转义。
谢谢 Paolo!
如果在 Windows 上,我可能会考虑使用 mkdirp (https://github.com/substack/node-mkdirp) 和 rimraf(https://npmjs.net.cn/package/rimraf)
我是不是错过了什么?除了“监视”(和 devDependencies)之外,此解决方案如何处理依赖关系链?NPM run-scripts 是否始终构建“所有内容”?
来自“make-land”,我想我太老派了,我就是不明白——我不想让构建步骤在不需要的情况下执行任何操作 :/
使用 parallelshell 和简单的管道 | 之间有区别吗?
我相信这将等同于 parallelshell
"start": "npm run watch | npm run server"
或类似的东西"deploy": "(npm run watch &) && npm run server"