• Background
  • Question
  • Reason
  • Solution
  • Summary

Background

  • Node.js
  • NPM
  • Gulp

Node.js

Node.js® is an open-source, cross-platform JavaScript runtime environment.

https://nodejs.org/en/

nodejs-1.png


Dependencies:

  • Libraries
    • V8
    • libuv
    • llhttp
    • c-ares
    • OpenSSL
    • zlib
  • Tools
    • npm
    • gyp
    • gtest

Standard library:

  • path, fs
  • net, http
  • process, child_process, cluster

NPM

npm is the package manager for Node.js. It was created in 2009 as an open source project to help JavaScript developers easily share packaged modules of code.

https://www.npmjs.com/about

npm-1.png


Some package:

  • ant-design, element-ui, material-ui
  • react, vue, angular
  • babel, typescript, eslint, postcss
  • gulp, webpack, vite

  • aws-sdk, axios, lodash
  • express, koa, nestjs, egg, midway
  • mongodb, redis, mysql

Gulp

A toolkit to automate & enhance your workflow

Leverage gulp and the flexibility of JavaScript to automate slow, repetitive workflows and compose them into efficient build pipelines.

https://gulpjs.com/

gulp.png

  • task
  • composable(pipe, series, parallel)
  • plugin

Question

1. Frist gulp test execution failed

➜  **-***-****** git:(dev) gulp test
ReferenceError: primordials is not defined
    at fs.js:36:5
    at req_ (/Users/*****/work/**-***-******/node_modules/natives/index.js:143:24)
    at Object.req [as require] (/Users/*****/work/**-***-******/node_modules/natives/index.js:55:10)
    at Object.<anonymous> (/Users/*****/work/**-***-******/node_modules/vinyl-fs/node_modules/graceful-fs/fs.js:1:37)
    ...

Reason

Gulp 3 is no longer supported.

https://github.com/gulpjs/gulp/issues/2324

  • Gulp v3.9.1 release time: 2019-04-22
  • Node v12.x initial release time: 2019-04-23

Because Gulp v3.x not support NodeJS v12 and above.

If switch to Node v10, can work normally.

Solution

Upgrade to Gulp v4:

npm i -D gulp@latest
-   "gulp": "^3.9.1",
+   "gulp": "^4.0.2",

Result

➜  **-***-****** git:(***) ✗ gulp test
AssertionError [ERR_ASSERTION]: Task function must be specified
    at Gulp.set [as _setTask] (/Users/*****/work/**-***-******/node_modules/undertaker/lib/set-task.js:10:3)
    at Gulp.task (/Users/*****/work/**-***-******/node_modules/undertaker/lib/task.js:13:8)
    at Object.<anonymous> (/Users/*****/work/**-***-******/tasks/deploy.js:4:6)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:101:18)
    at requireDir (/Users/*****/work/**-***-******/node_modules/require-dir/index.js:128:33)

2. Second gulp test execution failed

➜  **-***-****** git:(***) ✗ gulp test
AssertionError [ERR_ASSERTION]: Task function must be specified
    at Gulp.set [as _setTask] (/Users/*****/work/**-***-******/node_modules/undertaker/lib/set-task.js:10:3)
    at Gulp.task (/Users/*****/work/**-***-******/node_modules/undertaker/lib/task.js:13:8)
    at Object.<anonymous> (/Users/*****/work/**-***-******/tasks/deploy.js:4:6)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:101:18)
    at requireDir (/Users/*****/work/**-***-******/node_modules/require-dir/index.js:128:33)

Reason

deploy.js:4:6

gulp.task("deploy", ["update_endpoint"], function () {
  // ...
});

Because gulp.task() second params need function, task arrays no longer supported.

And if want to support task serialization, need use gulp.series().

gulp-api-1.png

Solution

Use new syntax/api refactor task code:

Case 1:

- gulp.task('deploy', ['update_endpoint'], function () {
- ...
+ ...
+ gulp.task("deploy", gulp.series("update_endpoint", upload));

Case 2:

- gulp.task('docs', function() {
- ...
+ ...
+ gulp.task("docs", function(cb) {
+  cb();

Other changes.

Result

After Change, gulp test can be exec on node v12 above:

Test

Task struct:

➜  **-***-****** git:(dev) gulp -T
Tasks for ~/work/**-***-******/gulpfile.js

├── build
├── update_endpoint
├─┬ deploy
│ └─┬ <series>
│   ├── update_endpoint
│   └── upload
├─┬ local-deploy
│ └─┬ <series>
│   ├── localUpdateEndpoint
│   └── upload
├── docs
├─┬ init
│ └─┬ <series>
│   ├── <anonymous>
│   ├── <anonymous>
│   └── copyCustom
├── copy-source
├─┬ package
│ └─┬ <series>
│   ├── copy-source
│   └── zipRelease
└── test

Teamcity

  • A build log on the first day: https://teamcity.***.io/viewLog.html?buildId=791019&buildTypeId=HliPortal_DevRc_GdHliPortal&tab=buildLog
  • A build log on the next day: https://teamcity.***.io/viewLog.html?buildId=791394&buildTypeId=HliPortal_DevRc_GdHliPortal&tab=buildLog

Local

NodeJS v14

In a clean git clone, use NodeJS v14(v14.20.0):

NodeJS v12

In a clean git clone, use NodeJS v12(v12.22.12):

  • gulp init
  • gulp test
  • gulp build
  • gulp docs
  • gulp local-deploy
  • gulp package
  • gulp –tasks

Thrid Question

gulp ** task exec failed, and missing dateformat module.

TODO: What caused ? package lock file ?

Reason

gulp-***@0.1.21 use gulp@3.9.1 is out of date.

➜  **-***-****** git:(dev) npm ls gulp
**-***-******@1.2.0 /Users/*****/work/**-***-******
├── gulp@4.0.2
└─┬ gulp-***@0.1.21
  └── gulp@3.9.1

The dateformat used in the project is a child dependency from gulp-***@0.1.21 the dependencies are as follows:

**-***-****** git:(dev) npm ls dateformat
**-***-******@1.2.0 /Users/*****/work/**-***-******
└─┬ gulp-***@0.1.21
  └─┬ gulp@3.9.1
    └─┬ gulp-util@3.0.8
      └── dateformat@2.2.0

Solution

Upgrade gulp-*** to v0.2.1:

npm i -D gulp-***@latest
npm i -D dateformat@latest
+    "dateformat": "^5.0.3",
...
-    "gulp-***": "^0.1.21",
+    "gulp-***": "^0.2.1",

Result

After change, the dependencies are as follows:

➜  **-***-****** git:(feature/upgrade-gulp-***-and-clear-unused-dependencies) npm ls gulp
**-***-******@1.2.0 /Users/*****/work/**-***-******
├── gulp@4.0.2
└─┬ gulp-***@0.2.1
  └── gulp@4.0.2  deduped

➜  **-***-****** git:(feature/upgrade-gulp-***-and-clear-unused-dependencies) npm ls dateformat
**-***-******@1.2.0 /Users/*****/work/**-***-******
└── dateformat@5.0.3

gulp package works normally:

Summary

  • Gulp ?
  • Node.js ?
  • NPM ?

Gulp ?

Gulp v3 not support Node v12 above:

And to clarify even further, the natives module would only come from a VERY outdated version of graceful-fs that is not included in gulp 4 so it’s going to be a different issue within your project (like an incorrect lockfile).

https://github.com/gulpjs/gulp/issues/2324#issuecomment-488646731

  • In Gulp v4, vinyl-fs from ^0.3.0 upgrade to ^3.0.0
  • while upgrading the primary dependency, graceful-fs as a sub dependency, is also upgraded from ^3.0.0 to ^4.0.0.
npm WARN deprecated graceful-fs@1.2.3: please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js

gulp-package-2.png

Node.js ?

  • Current - Should incorporate most of the non-major (non-breaking) changes that land on nodejs/node main branch.
  • Active LTS - New features, bug fixes, and updates that have been audited by the LTS team and have been determined to be appropriate and stable for the release line.
  • Maintenance - Critical bug fixes and security updates. New features may be added at the discretion of the LTS team - typically only in cases where the new feature supports migration to later release lines.

https://github.com/nodejs/release#release-schedule

  • The versions before Node v14 are outdated
  • Node v14 end-of-line is 2023-04-30
  • Node v18 enter LTS status schedule.svg
  • Node package security
  • More feature and better performance

NPM ?

Released with NodeJS.

npm-2.png

  • More feature and better performance
    • package lock file
    • overrides

Other NodeJS package manager:

  • Yarn
  • PNPM

PNPM

pnpm stands for performant npm. @rstacruz came up with the name.

https://pnpm.io/faq

pnpm.jpeg

pnpm-node-modules-structure.jpeg

When installing dependencies with npm or Yarn Classic, all packages are hoisted to the root of the modules directory. As a result, source code has access to dependencies that are not added as dependencies to the project.

By default, pnpm uses symlinks to add only the direct dependencies of the project into the root of the modules directory.

References