npm构建脚本_NPM脚本简介

罗祺
2023-12-01

npm构建脚本

by Mohammed Ajmal Siddiqui

由Mohammed Ajmal Siddiqui

NPM脚本简介 (Introduction to NPM Scripts)

NPM scripts are among my favorite features of NPM. They are simple. They reduce the need for tools. Hence they reduce the number of configuration files and other things you need to keep track of. And they are very versatile. They also let you automate a lot of common tasks. some of which are listed towards the end of the article.

NPM脚本是我最喜欢的NPM功能之一。 他们很简单。 它们减少了对工具的需求。 因此,它们减少了配置文件的数量以及您需要跟踪的其他内容。 而且它们非常通用。 它们还使您可以自动化许多常见任务。 其中一些在文章结尾处列出。

Without further ado, let’s dive into NPM scripts!

事不宜迟,让我们深入了解NPM脚本!

什么是NPM脚本? (What are NPM Scripts?)

NPM scripts are, well, scripts. We use scripts to automate repetitive tasks. For example, building your project, minifying Cascading Style Sheets (CSS) and JavaScript (JS) files. Scripts are also used in deleting temporary files and folders, etc,. There are many ways to pull this off — you could write bash/batch scripts, or use a task runner like Gulp or Grunt. However, a lot of people are moving over to NPM scripts for their simplicity and versatility. They also offer possibility of having fewer tools to learn, use, and keep track of.

NPM脚本就是脚本。 我们使用脚本来自动执行重复性任务。 例如,构建项目,最小化级联样式表(CSS)和JavaScript(JS)文件。 脚本还用于删除临时文件和文件夹等。 有很多方法可以实现这一目标-您可以编写bash / batch脚本,也可以使用任务运行程序,例如Gulp或Grunt。 但是,许多人由于其简单性和多功能性而转向NPM脚本。 它们还提供了更少的工具来学习,使用和跟踪的可能性。

Now that we have (some) idea of what NPM scripts are and what they can do for us, let’s go ahead and write some!

现在,我们已经了解了NPM脚本是什么以及它们可以为我们做些什么,让我们继续写一些吧!

package.json中的脚本对象 (The Scripts Object in package.json)

Most of our work will happen in the package.json file that NPM uses as a manifest of sorts. This is the file that is created when you run npm init.

我们的大部分工作将在NPM用作各种清单的package.json文件中进行。 这是在运行npm init.时创建的文件npm init.

Here’s a sample package.json file:

这是一个示例package.json文件:

{       "name": "super-cool-package",       "version": "1.0.0",       "scripts": {            ...       },     "dependencies": {         ...    }        "devDependencies": {             ...       } }

If you’ve been working with NodeJS and NPM, you will be familiar with the package.json file. Notice the scripts object in the file. This is where our NPM scripts will go. NPM scripts are written as usual JSON key-value pairs where the key is the name of the script and the value contains the script you want to execute.

如果您一直在使用NodeJS和NPM,则将熟悉package.json文件。 注意文件中的scripts对象。 这就是我们的NPM脚本的去向。 NPM脚本像通常的JSON键值对那样编写,其中键是脚本的名称,值包含要执行的脚本。

Here’s perhaps the most popular NPM script (and it’s also a special kind of script):

这也许是最受欢迎的NPM脚本(也是一种特殊的脚本):

"scripts": {    "start": "node index.js",    ...}

You’ve probably seen this tons of times in your package.json files. And you probably know that you can type npm start to execute the script. But this example illustrates the first important aspect of NPM scripts — they are simply terminal commands. They run in the shell of the OS on which they’re executed. So it might be bash for Linux and cmd.exe for Windows.

您可能已经在package.json文件中看到了无数次。 您可能知道您可以键入npm start来执行脚本。 但是此示例说明了NPM脚本的第一个重要方面-它们只是终端命令。 它们在执行它们的操作系统的外壳中运行。 因此,对于Linux而言可能是bash,对于Windows而言可能是cmd.exe。

At this point, you might be rather unimpressed. But keep reading to see how powerful NPM scripts really are.

在这一点上,您可能不为所动。 但是请继续阅读以了解NPM脚本的真正功能。

自定义脚本 (Custom Scripts)

The script we just saw is one of the “special” NPM scripts. You can execute it by simply typing npm start. These are scripts with names that NPM recognizes and attaches special meaning to. For example, you can write a script called prepublish. NPM will execute the script before your package is packed and published, and also when you run npm install locally without any arguments. More on such scripts here.

我们刚刚看到的脚本是“特殊” NPM脚本之一。 您只需键入npm start即可执行它。 这些脚本的名称可以被NPM识别并具有特殊含义。 例如,您可以编写一个名为prepublish的脚本。 NPM将在打包和发布软件包之前以及在运行npm install不带任何参数的情况下执行脚本。 更多关于这些脚本在这里

But NPM also let’s you define your own custom scripts. This is where the power of NPM scripts starts to show itself.

但是NPM也让您定义自己的自定义脚本。 这就是NPM脚本强大的地方。

Let’s look at a super basic custom NPM script that outputs “hello world” to the console. Add this to the scripts object of your package.json file:

让我们看一个将“ hello world”输出到控制台的超基本定制NPM脚本。 将此添加到package.json文件的scripts对象中:

"say-hello": "echo 'Hello World'"

The scripts object in your package.json file should look like this:

package.json文件中的脚本对象应如下所示:

..."scripts": {    "start": "node index.js",    "say-hello": "echo 'Hello World!'"}

Now try running npm say-hello. Doesn’t work? This is because custom NPM scripts must be preceded by either run-script or run for them to be executed correctly. Try running npm run-script say-hello or npm run say-hello. The console says, “Hello World!”! We’ve written our first NPM script!

现在尝试运行npm say-hello 。 不行吗 这是因为自定义NPM脚本必须在run-script之前或run后才能正确执行。 尝试运行npm run-script say-hellonpm run say-hello 。 控制台说:“ Hello World!”! 我们已经编写了第一个NPM脚本!

Here’s a quick tip — in order to prevent the default NPM logs from outputting to the console when you execute a script, add the --silent flag. This is what your command would look like:

快速提示-为了防止执行脚本时默认的NPM日志输出到控制台,请添加--silent标志。 这是您的命令如下所示:

npm run --silent say-hello

在其他NPM脚本中调用NPM脚本 (Calling NPM Scripts Within Other NPM Scripts)

One downside of using NPM scripts shows up when your script is fairly complex (and long). This problem is compounded by the fact that the JSON spec does not support comments. There are a few ways around this problem. One way is to divide your script into small single-purpose scripts and then call them within other NPM scripts. The way to call an NPM script within another is straightforward. Modify your scripts object so that it looks like this:

当您的脚本相当复杂(而且很长)时,使用NPM脚本的一个缺点就会显现出来。 JSON规范不支持注释的事实使问题更加复杂。 有几种方法可以解决此问题。 一种方法是将您的脚本划分为小型的单用途脚本,然后在其他NPM脚本中调用它们。 在另一个内部调用NPM脚本的方法很简单。 修改scripts对象,使其如下所示:

"scripts": {    "say-hello": "echo 'Hello World'",    "awesome-npm": "npm run say-hello && echo 'echo NPM is awesome!'"}

Since NPM scripts execute in the shell, calling npm run say-hello within another NPM script is almost intuitive.

由于NPM脚本在外壳中执行,因此在另一个NPM脚本中调用npm run say-hello几乎是直观的。

For those of you who are not very comfortable with terminal commands, the &&in the script is used to delimit two commands. Thus, the second command executes after the successful execution of the first command.

对于不熟悉终端命令的人,脚本中的&&用于分隔两个命令。 因此,第二条命令在成功执行第一条命令后执行。

Now when you run npm run awesome-npm, the say-hello script executes first, outputting “Hello World” to the console, followed by the part of the script after the &&, which outputs “NPM is awesome!”

现在,当您运行npm run awesome-npm ,将首先执行say-hello脚本,然后将“ Hello World”输出到控制台,然后是脚本中&&之后的部分,输出“ NPM很棒!”。

Here’s a use case where this might be useful. Suppose you’re automating the build process of your application. Let’s say you’re using Webpack as a bundler and your distribution code goes into a directory called “dist”.

这是一个有用的用例。 假设您正在自动化应用程序的构建过程。 假设您将Webpack用作捆绑程序,并且您的分发代码进入了一个名为“ dist”的目录。

You might start with cleaning the directory. This can be done by either deleting its contents or deleting the directory itself and then making it again. Let’s go with the latter approach. Your command might look something like this:

您可能首先要清理目录。 可以通过删除其内容或删除目录本身,然后再次进行创建。 让我们采用后一种方法。 您的命令可能如下所示:

rm -r dist && mkdir dist
Note that this uses bash commands. You will learn how to write cross-platform NPM scripts later in this article.
请注意,这使用bash命令。 您将在本文后面学习如何编写跨平台NPM脚本。

After this, you might invoke the bundler by executing the webpack command.

此后,您可以通过执行webpack命令来调用捆绑webpack

You can execute these commands in succession by using the &&operator. However, for the sake of demonstration and modularity, let’s split this into two NPM scripts that call each other.

您可以使用&&运算符连续执行这些命令。 但是,为了演示和模块化,让我们将其分为两个相互调用的NPM脚本。

Here’s what the scripts object would look like in this use case:

在此用例中,脚本对象如下所示:

"scripts": {    ...    "clean": "rm -r dist && mkdir dist",    "build": "npm run clean && webpack"}

There you have it! How to split a more complex task into smaller NPM scripts.

你有它! 如何将更复杂的任务分解为较小的NPM脚本。

调用Shell和节点脚本 (Calling Shell and Node Scripts)

At times, you may have to write scripts far more complex than ones that can be achieved in 2–3 commands. When this situation arises, one solution is to write bash or JS scripts (or scripts in any scripting language you like) and call them from NPM scripts.

有时,您可能不得不编写比2–3命令可以实现的脚本复杂得多的脚本。 当出现这种情况时,一种解决方案是编写bash或JS脚本(或您喜欢的任何脚本语言的脚本)并从NPM脚本中调用它们。

Let’s quickly write a bash script that says hello to you. Create a file called hello.sh in your root directory and paste this code in it:

让我们快速编写一个bash脚本,向您问好。 在您的根目录中创建一个名为hello.sh的文件,并将以下代码粘贴到其中:

#!/usr/bin/env bash
# filename: hello.shecho "What's your name?"read nameecho "Hello there, $name!"

It’s a simple script that echoes your name back to you. Now modify the package.json file so that the scripts object has this line of code:

这是一个简单的脚本,可将您的名字呼应给您。 现在修改package.json文件,以便scripts对象具有以下代码行:

"bash-hello": "bash hello.sh"

Now, when you run npm run bash-hello, it asks you for your name and then says hello to you! Brilliant.

现在,当您运行npm run bash-hello ,它将询问您的名字,然后向您问好! 辉煌。

You can do the same thing with JS scripts run using node. An advantage of this approach is that this script will be platform independent since it uses node to run. Here’s a slightly more complex JS script to add two integers received as command line arguments (put this in a file named add.js):

您可以对使用node运行的JS脚本执行相同的操作。 这种方法的优点是该脚本将独立于平台,因为它使用节点运行。 这是一个稍微复杂一点的JS脚本,用于添加作为命令行参数接收的两个整数(将其放入名为add.js的文件中):

// add.js// adds two integers received as command line arguments
function add(a, b) {    return parseInt(a)+parseInt(b);}
if(!process.argv[2] || !process.argv[3]) {    console.log('Insufficient number of arguments! Give two numbers please!');}
else {    console.log('The sum of', process.argv[2], 'and', process.argv[3], 'is', add(process.argv[2], process.argv[3]));}

The process.argv object contains the command line arguments given to the script. The first two elements, process.argv[0] and process.argv[1], are reserved by node. Thus process.argv[2] and process.argv[3] let you access the command line arguments.

process.argv对象包含提供给脚本的命令行参数。 前两个元素process.argv[0]process.argv[1]由节点保留。 因此, process.argv[2]process.argv[3]让您访问命令行参数。

Now add this line to the scripts object of the package.json file:

现在将此行添加到package.json文件的scripts对象中:

"js-add": "node add.js"

Finally, run the script as an npm script by giving it two numbers as command line arguments:

最后,通过为脚本提供两个数字作为命令行参数,将该脚本作为npm脚本运行:

npm run js-add 2 3

And viola! The output is

和中提琴! 输出是

The sum of 2 and 3 is 5

Brilliant! Now we’re capable of writing much more powerful scripts and leveraging the power of other scripting languages.

辉煌! 现在,我们能够编写功能更强大的脚本,并利用其他脚本语言的功能。

前后挂钩 (Pre and Post Hooks)

Remember how we talked about a special npm script called prepublish that runs before you publish your package? Such a functionality can be achieved with custom scripts too. We’ve discussed one way to do this in the previous section. We can chain commands using the &&operator, so if you wanted to run script-1 before script-2, you would write:

还记得我们如何谈论过一个特殊的npm脚本,称为prepublish ,该脚本在发布程序包之前运行吗? 这样的功能也可以通过自定义脚本来实现。 在上一节中,我们讨论了实现此目的的一种方法。 我们可以使用&&运算符链接命令,因此,如果要在script-2之前运行script-1,则应编写:

"script-2": "npm run script-1 && echo 'I am script-2'"

However, this makes our scripts a little dirty. This is because the core functionality of the script is reflected only in the second part of the command (after the && ). One way to write clean scripts is to use pre and post hooks.

但是,这使我们的脚本有点脏。 这是因为脚本的核心功能仅反映在命令的第二部分(在&& )。 编写干净脚本的一种方法是使用前后钩子。

Pre and post hooks are exactly what they sound like — they let you execute scripts before and after you call a particular script. All you have to do is define new scripts with the same name as your main script. Yet these are prefixed with “pre” or “post” depending on whether the script is executed before the main script or after it.

前和后挂钩确实听起来像—它们使您可以在调用特定脚本之前和之后执行脚本。 您要做的就是定义与主脚本同名的新脚本。 但是,这些脚本的前缀是“ pre”或“ post”,具体取决于脚本是在主脚本之前执行还是在主脚本之后执行。

Let’s look at our say-hello script again. Say we want to execute the command echo 'I run before say-hello' before say-hello and echo 'I run after say-hello' after say-hello. This is what your scripts object would look like:

让我们再次看看我们的say-hello脚本。 说,我们要执行的命令echo 'I run before say-hello'之前say-helloecho 'I run after say-hello'后说问候。 这是您的脚本对象的样子:

"scripts": {    "say-hello": "echo 'Hello World'",     "presay-hello": "echo 'I run before say-hello'",    "postsay-hello": "echo 'I run after say-hello'" }

The “pre” and “post” before the script names tell npm to execute these before and after the script called say-hello respectively.

脚本名称之前的“ pre”和“ post”告诉npm分别在名为say-hello的脚本之前和之后执行它们。

Now, when you run npm run say-hello, the output of all three scripts shows up in order! How cool is that?

现在,当您运行npm run say-hello ,所有三个脚本的输出npm run say-hello顺序显示! 多么酷啊?

Since all three scripts output to the console and the NPM logs clutter the output, I prefer using the -silent flag while running these. So your command would look like this:

由于所有三个脚本输出到控制台,并且NPM日志使输出混乱,因此我更喜欢在运行这些脚本时使用-silent标志。 因此,您的命令将如下所示:

npm run --silent say-hello

And here’s the output:

这是输出:

I run before say-helloHello WorldI run after say-hello

There you have it!

你有它!

Let’s apply this knowledge to our build script example. Modify your package.json file so that it looks like this:

让我们将此知识应用于我们的构建脚本示例。 修改package.json文件,使其如下所示:

"scripts": {    ...    "clean": "rm -r dist && mkdir dist",     "prebuild": "npm run clean"    "build": "webpack"}

Now our scripts look much cleaner. When you run npm run build, prebuildis called because of the “pre” hook, which calls clean, which cleans up our dist directory for us. Sweet!

现在,我们的脚本看起来更加简洁。 当您运行npm run build ,由于“ pre”钩子而调用了prebuild ,该钩子调用clean ,为我们清理了dist目录。 甜!

使我们的脚本跨平台 (Making Our Scripts Cross-Platform)

There is one drawback of writing terminal/shell commands in our scripts. This is the fact that shell commands make our scripts platform dependently. This is perhaps what draws our attention to tools like Gulp and Grunt. If your script is written for Unix systems, chances are, it won’t work on Windows, and vice versa.

在我们的脚本中编写终端/ shell命令有一个缺点。 这是Shell命令独立地使我们的脚本平台成为事实的事实。 这也许是吸引我们注意Gulp和Grunt之类的工具的原因。 如果您的脚本是为Unix系统编写的,则很有可能,它将无法在Windows上运行,反之亦然。

The first time I used NPM scripts, which called other bash/batch scripts, I thought of writing two scripts per task. One for Unix and one for the Windows command line. This approach may work in use cases where the scripts aren’t that complex and there aren’t many scripts. However, it quickly becomes clear that they are not a good solution to the problem. Some of the reasons behind this are:

第一次使用NPM脚本(称为其他bash / batch脚本)时,我想到为每个任务编写两个脚本。 一种用于Unix,另一种用于Windows命令行。 在脚本不是那么复杂并且脚本不多的用例中,这种方法可能会起作用。 但是,很快就知道它们不是解决问题的好方法。 这背后的一些原因是:

  • You have another thing to keep track of that distracts you from your primary task of working on the application. Instead, you end up working in the development environment.

    您还有另一件事需要注意,这会使您分心于处理应用程序的主要任务。 相反,您最终将在开发环境中工作。
  • You’re writing redundant code — the scripts you write are very similar and accomplish the same task. You’re essentially rewriting code. This violates one of the fundamental principles of coding — DRY: Don’t Repeat Yourself.

    您正在编写冗余代码-您编写的脚本非常相似,并且可以完成相同的任务。 您实质上是在重写代码。 这违反了编码的基本原理之一-DRY:不要重复自己。

So how do we get around this? There are three approaches that you may use:

那么我们如何解决这个问题? 您可以使用三种方法:

  1. Use commands that run cross-platform: Many useful commands are common to Unix and Windows. If your scripts are simple, consider using those.

    使用跨平台运行的命令: Unix和Windows有许多有用的命令。 如果您的脚本很简单,请考虑使用这些脚本。

  2. Use node packages: You can use node packages like rimraf or cross-env instead of shell commands. And obviously, you can use these packages in JS files if your script is large and complex.

    使用节点程序包:您可以使用rimrafcross-env之类的节点程序包代替shell命令。 显然,如果脚本很大且很复杂,则可以在JS文件中使用这些软件包。

  3. Use ShellJS: ShellJS is an npm package that runs Unix commands via Node. So this gives you the power to run Unix commands on all platforms, including Windows.

    使用ShellJS: ShellJS是一个npm软件包,可通过Node运行Unix命令。 因此,这使您能够在包括Windows在内的所有平台上运行Unix命令。

The above approaches were taken from this brilliant article by Cory House about why he left Grunt and Gulp for NPM scripts. The article details many things not covered in this series and concludes with a list of excellent resources. I would definitely recommend that you read it to further your understanding of NPM scripts.

以上方法来自Cory House的 这篇精彩文章 ,内容涉及他为何离开Grunt和Gulp从事NPM脚本工作。 本文详细介绍了本系列中未涉及的许多内容,并以一系列出色的资源作为结尾。 我绝对建议您阅读它,以进一步了解NPM脚本。

NPM脚本的几个用例 (A Few Use Cases for NPM Scripts)

Finally, there is a lot that you can do with NPM scripts. Some use cases are:

最后,NPM脚本可以做很多事情。 一些用例是:

  • Minification/Uglification of CSS/JavaScript

    CSS / JavaScript的最小化/丑化
  • Automating the build process

    自动化构建过程
  • Linting your code

    整理你的代码
  • Compressing images

    压缩影像
  • Automatically injecting changes with BrowserSync

    使用BrowserSync自动注入更改

And a lot more. To learn about how to automate the above-mentioned tasks using NPM scripts, check out this brilliant article on the topic.

还有更多。 要了解如何使用NPM脚本自动执行上述任务,请查看有关该主题的精彩文章

奖励:使用NodeJS创建CLI应用程序的指挥官 (Bonus: Commander for Creating CLI Applications Using NodeJS)

While we’re discussing NPM scripts and the CLI, I’d like to quickly tell you about a really cool package called commander. Commander allows you to create your own CLI applications. This isn’t really related to NPM scripts, but it’s a cool piece of technology to know. Check out the commander docs here or try one of these tutorials:

当我们讨论NPM脚本和CLI时,我想快速告诉您一个叫做Commander的非常酷的程序包。 Commander允许您创建自己的CLI应用程序。 这实际上与NPM脚本无关,但它是一项很酷的技术。 在此处查看Commander文档或尝试以下教程之一:

结论词 (Concluding Words)

That is all for this article on using NPM scripts. I hope you’ve gained some insight on how you can integrate these into your own projects. This article is by no means an in-depth tutorial on NPM scripts. Hence I’d recommend you learn further both from other resources and from actually using NPM scripts in your own projects.

这就是本文有关使用NPM脚本的全部内容。 希望您对如何将它们集成到自己的项目中有所了解。 本文决不是有关NPM脚本的深入教程。 因此,我建议您从其他资源以及在自己的项目中实际使用NPM脚本中进一步学习。

Also, do connect with me on GitHub and LinkedIn.

另外,请在GitHubLinkedIn上与我联系。

Happy Coding! :)

编码愉快! :)

翻译自: https://www.freecodecamp.org/news/introduction-to-npm-scripts-1dbb2ae01633/

npm构建脚本

 类似资料: