Nicolas Bevacqua A task of comparing the JavaScript build (Yi) system. He compared the Big Three: Grunt, Gulp and NPM, and discussed the pros and cons of each.
by Nicolas Bevacqua
It is always difficult to decide which technology to use. Once you encounter a problem, you don't want to overturn your previous choice. But you have to choose one, and then let it follow your thoughts. The same is true for a set of constructs (Yi), and you should think of it as a very important choice, let's take grunt as an example.
- grunt has a complete community, even on Windows
-
-
- You don't need more advanced ideas, and you don't need any experience.
These are good reasons to build Yi tools with grunt, but I would like to clarify that I do not think Grunt is the only best option. There are also some of the same popular options there, some of which may be better than grunt.
I'm writing this article to help you understand the difference between Grunt,gulp and NPM, which is the three building tools I've used most in front-end development work.
Let's talk about what Grunt is good at. Grunt: Good part
One of the best aspects of grunt is its ease of use. It makes it almost effortless for programmers to use JavaScript to build Yi tools. You just need to find the right plug-ins, read their documentation, and then install and configure it. This ease of use means that large development teams, those with different skill levels, can have no hassle adjusting the Yi process to meet the latest needs of the project. And the team doesn't need to be proficient in node, they just need to configure the object to add different tasks to the different sequence build Yi process.
With a large enough plug-in library, you will find that you hardly need to develop your own compilation tasks, which will enable you and your team to quickly build development tools that are critical if you want to quickly complete the Yi process, and you can take steps to improve the strategy of the compilation process.
Managing deployment through Grunt is also possible because there are many packages that can be completed for these tasks, such as Grunt-git, Grunt-rsync, or GRUNT-EC2, and so on.
So, what's the flaw with grunt? If you have an apparently complex Yi process, it may become overly verbose. When developed for a period of time, it is often difficult to make the Yi process as a whole. Once you've compiled the Yi process task to reach two digits, it is almost guaranteed that you will find yourself having to run the same task in multiple targets (Targets) so that you can perform the task flow correctly. Because tasks need to be configured, it's hard to figure out the actual order in which the tasks are executed.
In addition, your team should be committed to writing maintainable code, when it comes to your Yi, such as using grunt, which means that you need to write a separate profile for each task (or each Yi stream) for your team to use.
Now, we have learned about the good and bad aspects of grunt, and under what circumstances it is better to be a Yi tool for your project. Let's talk about NPM, how it is used as a build tool, and how it differs from grunt.
Consider NPM as a build tool
In order to use NPM as a build tool, you need a Package.json and NPM. Making NPM tasks is as simple as adding attributes to a script. The name of the property is used as the task name and the command that will be executed. The build task below will pre-check that there are no syntax errors in our JavaScript code, using the Jshint command line interface. You can run any shell you want on the command line.
{" scripts": { "test": "Jshint". --exclude node_modules " }, " Devdependencies ": { " jshint ":" ^2.5.1 " }}
Once the definition is complete, you can run it with the following command
NPM Run Test
It is important to note that NPM provides shortcuts for running specific tasks. For example, to run test, you can simply use NPM test and omit the verb run. You can link a series of NPM run tasks together through a chain of commands to form your Yi process:
{" scripts": { "lint": "Jshint". --exclude node_modules ", " unit ":" Tape test/* ", " test ":" NPM run lint && npm run unit " }, " Devdependencies ": { " jshint ":" ^2.5.1 ", " tape ":" ~2.10.2 " }}
You can also schedule some tasks to be completed in the background, and then have them sync. Suppose we have the following package file, we will copy out a directory to put JavaScript files, and stylus The style sheet file we write with Yi into CSS. In this case, it is ideal to run multiple tasks together. can also be implemented, using the & delimiter.
{" scripts": { "Build-js": "Cp-r src/js/vendor bin/js", "build-css": "Stylus Src/css/all.styl-o bin/css", "Build": "NPM run Build-js & npm run Build-css" }, "Devdependencies": { "stylus": "^0.45.0" }}
To learn more about using NPM as a build tool, you should learn to write bash commands first.
task dependencies for installing NPM
The Jshint CLI is not necessarily included in your system, there are two ways to install it. If you are looking for a tool to run directly from the command line, then you should install it globally, using the G flag, as shown below.
NPM install-g Jshint
However, if you are using a package that is used in NPM run, you should add it to devdependency as shown below. This will allow NPM to automatically find out where in the system it depends on where the jshint is installed. This method applies to any command-line tool and all operating systems.
NPM Install--save-dev Jshint
You are not only restricting the use of CLI tools. In fact, NPM can run any shell script. Let's dig!
Using shell scripts in NPM
The following is a script that runs in node and displays a random emoji string (emoji-random). The first line specifies the run environment, which is based on node.
#!/usr/bin/env Nodevar emoji = require (' emoji-random '); var emo = Emoji.random (); Console.log (emo);
If you put a script file named emoji into your project's root directory, you must declare emoji-random as a dependency and add the following script command to the package file.
{" scripts": { "emoji": "./emoji" }, "Devdependencies": { "emoji-random": "^0.1.2 "}}
Once written, you only need to run NPM run emoji at the command line.
The good and the bad aspects
Using NPM as a building tool has several advantages over grunt. You will not be bound by the grunt plugin, you can take advantage of all of NPM's advantages, it has tens of thousands of modules to choose from. In addition to NPM, you do not need any additional command line tools (CLI) or files, you only need to add dependencies in Package.json. Since NPM runs command-line tools (CLI tools) and bash commands, this is better than the way grunt executes.
One of the biggest drawbacks of grunt is its I/O limitations. This means that most grunt tasks are read from disk and then written to disk. If you have multiple tasks that need to operate on the same file, it is likely that the file will be read multiple times from disk. In bash, commands are passed directly through the pipeline to the next task, avoiding grunt additional I/O overhead.
Perhaps the biggest drawback of NPM is that applications in Windows environments may not be as good. This means that open source projects running with NPM may experience problems. This also means that Windows developers try to use NPM alternatives. This drawback almost excludes npm from Windows.
Gulp, another build tool that proposes features similar to grunt and NPM, you'll find out.
Gulp's Streaming build tool
Similar to grunt, it relies on plug-ins and is cross-platform, and it also supports Windows. Gulp is a code-driven build tool that, contrary to Grunt's declarative definition task, makes its task definition easier to read. Gulp also has something similar to NPM run because it uses the node stream to convert the input and output. This means that gulp does not have the problem of grunt disk-intensive I/O operations. It's also why it's faster than GRUNP, and less time spent on I/O.
The main disadvantage of using Gulp is that it relies heavily on streams, pipelines, and asynchronous code. Don't get me wrong: This is definitely an advantage if you use it in node. However, unless you and your team are very well versed in node, you are likely to encounter problems dealing with streams, especially if you are building your own Gulp task plugin.
While working as a team, gulp is not a discouraged npm, because most front-end teams may understand JavaScript, but they may not be so skilled at bash scripts, some of which may be using Windows! That's why I usually recommend that you run NPM on your personal project. If your team is familiar with node, you can use Gulp. Of course, this is my personal advice and you should find the tools that best suit you and your team. In addition, you should not limit yourself to Grunt,gulp, or NPM run, which is just a tool for you and me. Try doing some small research, and maybe you'll find that you like even better tools than these three.
Let's look at some examples of what a task in gulp looks like.
Run the test in Gulp
There are some conventions gulp very similar to grunt. There is a file gruntfile.js in grunt that defines the task, called Gulpfile.js in Gulp. Another small difference is that in gulp, the CLI is already contained in the same gulp package, and you need to install it locally and globally via NPM.
Touch gulpfile.jsnpm install-g gulpnpm Install--save-dev Gulp
Before I start, I'll create a grulp task to process a JavaScript file, as you've already seen in Grunt and NPM, and you'll need to install Gulp-jshint,gulp's Jshint plugin first.
NPM Install--save-dev Gulp-jshint
Now that you've loaded the CLI both globally and locally, the Gulp and Gulp-jshint plugins have been installed locally, and you can synthesize one of these build tasks. You can write it in the Gulpfile.js file.
First, you will use Gulp.task to define a task and function. This feature contains all the necessary code to run the test. Here, you should use GULP.SRC to create a stream that reads your source files, which are piped into the Jshint plugin. Then, all you need to do is to print the Jshint task in the pipeline to the terminal. The following are the results shown in Gulpfile.
var gulp = require (' gulp '), var jshint = require (' Gulp-jshint '), Gulp.task (' Test ', function () { return Gulp . SRC ( './sample.js '). pipe (Jshint ()) . Pipe (Jshint.reporter (' Default '));});
One more thing to mention is that the Grulp stream will be transferred to the next task after a task has completely ended. You can use a Jshint reporter to make the output more concise and easier to read. Jshint reporter does not require GRULP plug-ins, such as Jshint-stylish, to allow us to install directly locally.
NPM Install--save-dev Jshint-stylish
The updated gulpfile should resemble the following. It loads the Jshint-stylish module and outputs it as a report format.
var gulp = require (' gulp '), var jshint = require (' Gulp-jshint '), Gulp.task (' Test ', function () { return Gulp . SRC ( './sample.js '). pipe (Jshint ()) . Pipe (Jshint.reporter (' jshint-stylish ');});
Done! This is the task of all a gulp named Test. It can be run with the following command as long as you install the global CLI.
Gulp Test
This is a fairly simple example. You can also create a write data stream to disk by using Gulp.dest. Let's take a look at another build task.
Create a library in Grulp
Before we get started, let's make it clear that the task: read the source file from disk Gulp.src and write back the content to gulp.dest through the disk pipeline, you can understand that just copy the file to another directory.
var gulp = require (' gulp '); Gulp.task (' Build ', function () { return Gulp . SRC ('./sample.js ') . PIPE ( Gulp.dest ('./build ');});
The copy file was completed, but it did not compress the JS file. To do this, you must use a gulp plugin. In this case, you can use Gulp-uglify, the popular uglifyjs compression codec Yi plugin.
var gulp = require (' gulp '); var uglify = require (' gulp-uglify '); Gulp.task (' Build ', function () { return gulp . src ('./sample.js ') . Pipe (Uglify ()) . Pipe (Gulp.dest ('./build ');});
As you might realize, streaming allows you to add more plug-ins instead of just reading and writing to disk once. You can also specify the size of the content in the buffer. It is important to note that if you add it before compressing it, then the size you get is unminified.
var gulp = require (' gulp '), var uglify = require (' gulp-uglify '), var size = require (' gulp-size '), Gulp.task (' Build ', function () { return Gulp . SRC ('./sample.js '). Pipe (Uglify ()). PIPE ( size ()). Pipe (gulp.dest ('./build ');});
To enhance this combination and satisfy the need to add or remove pipelines, let's add the last plug-in. This time, I'll use Gulp-header to add a piece of copyright information to the header file, such as name, version, and license type.
var gulp = require (' gulp '), var uglify = require (' gulp-uglify '), var size = require (' gulp-size '); var header = require (' gulp- var pkg = require ('./package.json '); var info = '//<%= pkg.name%>@v<%= pkg.version%>, <%= pkg.li Cense%>\n '; Gulp.task (' Build ', function () { return Gulp . SRC ('./sample.js ') . Pipe (Uglify ()) . Pipe (header (info, {pkg:pkg})). Pipe ( size ()) . Pipe (Gulp.dest ('./build '));});
Just like grunt, in Grulp you can define a process by passing a set of tasks to Gulp.task. In this regard, the main difference between grunt and Grulp is that grunt is synchronous, and Grulp is asynchronous.
Gulp.task (' Build ', [' build-js ', ' build-css ']);
In gulp, if you want to have the task run synchronously, you must declare a task. Execute before your task begins.
Gulp.task (' Build ', [' dep '], function () { //perform DEP-dependent tasks});
If you have any gains, look at this passage first.
It
doesn't matter what kind of tool you use, just make sure that the process build (Yi) is easy to use and don't work too hard.
Original address: HTTP://MODERNWEB.COM/2014/08/04/CHOOSE-GRUNT-GULP-NPM
JavaScript build (Yi) system big battle: Grunt vs. Gulp vs. NPM