preface

The composition and release of NPM modules have been mentioned in previous articles. Recently, I have been working on the development of a third-party SDK, using LERNA for the maintenance of NPM packages and TS for development and testing.

Of course, the SDK’s packaging tools use rollup. We won’t compare rollup with WebPack. Vue and React also use Rullup. Let’s start by detailing some of the stories that happened when Rollup met Axios.

The code for

The directory structure is as follows:

╰ ─ ➤ tree - 2 - L I node_modules. ├ ─ ─ Babel. Config. Js ├ ─ ─ build │ ├ ─ ─ index. The js │ └ ─ ─ a rollup. Config. Js ├ ─ ─ index. The ts ├ ─ ─ ├─ SRC │ ├─ ├─ ├.txt TXT ├─ ├.txt TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXTCopy the code
// package.json
{
  "name": "rollup-test"."version": "0.1.0 from"."private": true."main": "index.js"."scripts": {
    "build": "tsc -d && tsc && npm run build:cjs && npm run build:es && npm run build:umd"."build:cjs": "cross-env TARGET=cjs node build/index.js"."build:es": "cross-env TARGET=es node build/index.js"."build:umd": "cross-env TARGET=umd node build/index.js"
  },
  "dependencies": {
    "cross-env": "^ 5.2.0." "."@babel/runtime": "^ 7.4.4." "."@babel/core": "^ 7.4.4." "."@babel/plugin-transform-runtime": "^ 7.4.4." "."@babel/preset-env": "^ 7.4.4." "."magic-string": "^ 0.25.1"."rollup": "^ 1.11.3"."rollup-plugin-babel": "^ 4.3.2." "."rollup-plugin-commonjs": "^ 9.3.4"."rollup-plugin-json": "^ 4.0.0"."rollup-plugin-node-builtins": "^ 2.1.2"."rollup-plugin-node-globals": "^ 1.4.0." "."rollup-plugin-node-resolve": "^ 4.2.4"."rollup-plugin-terser": "^ 4.0.4." "."standard-version": "^ the 6.0.1." "."typescript": "^ 3.1.6." "
  },
  "devDependencies": {
    "axios": "^ 0.19.0"}}Copy the code
// rollup.config.js
"use strict";

const commonjs = require("rollup-plugin-commonjs");
const resolve = require("rollup-plugin-node-resolve");

const babel = require("rollup-plugin-babel");
const { terser } = require("rollup-plugin-terser");
const json = require("rollup-plugin-json");

const inputOptions = {
  plugins: [
    resolve(),
   
    commonjs({
      browser: true
    }),
    babel({
      exclude: ["node_modules/**"].runtimeHelpers: true
    }),
    terser(),
    json()
  ]

};

const outputOptions = {
  exports: "named"
};

module.exports = { inputOptions, outputOptions };

Copy the code
// src/index.ts
import axios from "axios";

async function testRollup() {
  console.log("test");
  await axios.get("");
}

export default testRollup;


Copy the code

The thinking process

Running NPM run build yields the following result:

╰ ─ ➤ NPM run build > [email protected] build/Users/leiliao ShopeeWorkspace/demoWorkspace/rollup - axios > TSC && node build/index.js'http'is imported by node_modules/axios/lib/adapters/http.js, Treating it as an external dependency'https'is imported by node_modules/axios/lib/adapters/http.js, Treating it as an external dependency'url'is imported by node_modules/axios/lib/adapters/http.js, Treating it as an external dependency'zlib'is imported by node_modules/axios/lib/adapters/http.js, Treating it as an external dependency'http'Is imported by commonJS-external-HTTP, but could not be resolved -- treating it as an external dependency'https'Is imported by commonJs-external-https, but could not be resolved -- treating it as an external dependency'url'Is imported by commonjs-external-URL, but could not be resolved -- treating it as an external dependency'zlib'Is imported by commonJS-external-zlib, but could not be resolved -- treating it as an external dependency'url'Is imported by node_modules/ follow-up redirects/index.js, but could not be cured -- treating it as an external dependency'http'Is imported by node_modules/ follow-up redirects/index.js, but could not be cured -- treating it as an external dependency'https'Is imported by node_modules/ follow-up redirects/index.js, but could not be cured -- treating it as an external dependency'assert'Is imported by node_modules/ follow-up redirects/index.js, but could not be cured -- treating it as an external dependency'assert'Is imported by commonJs-external-assert, but could not be resolved -- treating it as an external dependency'stream'Is imported by node_modules/ follow-up redirects/index.js, but could not be cured -- treating it as an external dependency'stream'Is imported by commonJS-external-stream, but could not be resolved -- treating it as an external dependency'tty'Is imported by node_modules/debug/SRC/node. Js, but could not be resolved, treating it as an external dependency'tty'Is imported by CommonJS-external-tty, but could not be resolved -- treating it as an external dependency'util'Is imported by node_modules/debug/SRC/node. Js, but could not be resolved, treating it as an external dependency'util'Is imported by commonJs-external-util, but could not be resolved -- treating it as an external dependency'os'Is imported by node_modules/supports color/index.js, but could not be resolved -- treating it as an external dependency'os'Is imported by commonJS-external-OS, but could not be resolved -- treating it as an external dependencyCopy the code

Modify the rollUp configuration based on the above error and add the External field

"use strict";

const commonjs = require("rollup-plugin-commonjs");
const resolve = require("rollup-plugin-node-resolve");

const babel = require("rollup-plugin-babel");
const { terser } = require("rollup-plugin-terser");
const json = require("rollup-plugin-json");

const inputOptions = {
  plugins: [
    resolve(),
   
    commonjs({
      browser: true
    }),
    babel({
      exclude: ["node_modules/**"],
      runtimeHelpers: true
    }),
    terser(),
    json()
  ],
   external: [
    "http"."https"."url"."assert"."stream"."tty"."util"."os"."zlib"]};const outputOptions = {
  exports: "named"
};

module.exports = { inputOptions, outputOptions };

Copy the code

Packing results are as follows

> [email protected] build: umd/Users/leiliao ShopeeWorkspace/demoWorkspace/rollup - axios > cross - env TARGET = umd node build/index.js No name was providedfor external module 'http' inThe output. Globals - guessing'http'
No name was provided for external module 'https' inThe output. Globals - guessing'https'
No name was provided for external module 'url' inThe output. Globals - guessing'url'
No name was provided for external module 'assert' inThe output. Globals - guessing'assert'
No name was provided for external module 'stream' inThe output. Globals - guessing'stream'
No name was provided for external module 'tty' inThe output. Globals - guessing'tty'
No name was provided for external module 'util' inThe output. Globals - guessing'util'
No name was provided for external module 'os' inThe output. Globals - guessing'os'
No name was provided for external module 'zlib' inThe output. Globals - guessing'zlib'
Creating a browser bundle that depends on Node.js built-in modules ('http'.'https'.'url'.'assert'.'stream'.'tty'.'util'.'os' and 'zlib'). You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins
Copy the code

When prompted to package the UMD format code, install rollup-plugin-node-builtins and use it in rollup.

"use strict";

const commonjs = require("rollup-plugin-commonjs");
const resolve = require("rollup-plugin-node-resolve");

const babel = require("rollup-plugin-babel");
const { terser } = require("rollup-plugin-terser");
const json = require("rollup-plugin-json");
const builtins = require("rollup-plugin-node-builtins");

const inputOptions = {
  plugins: [
    resolve(),
    builtins(),
    commonjs({
      browser: true
    }),
    babel({
      exclude: ["node_modules/**"],
      runtimeHelpers: true
    }),
    terser(),
    json()
  ]

};

const outputOptions = {
  exports: "named"
};

module.exports = { inputOptions, outputOptions };

Copy the code

Package to get the following information

Circular dependency: node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/duplex.js -> node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/readable.js -> node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/duplex.js
Circular dependency: node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/duplex.js -> node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/writable.js -> node_modules/rollup-plugin-node-builtins/src/es6/readable-stream/duplex.js
Copy the code

Why not use the official tooltip? Let’s see if the typed package works (I thought it was just Warnning at first) and run the current project using NPM link

╰─➤  npm link
audited 3216 packages in6.82s found 26 Moderate severity run 'NPM audit' fix 'to fix them, or' NPM audit 'after all the December attacksforThe details/Users/leiliao/NVM/versions/node/v10.15.3 / lib/node_modules/rollup - test - > / Users/leiliao /... /demoWorkspace/rollup-axiosCopy the code

Then reference it in a new project

╰ ─ ➤ NPM link rollup - test/Users/leiliao/ShopeeWorkspace/otherEWokspace/ts - vuex - demo/node_modules/rollup - test - > / Users/leiliao/NVM/versions/node/v10.15.3 / lib/node_modules/rollup - test - > /Users/leiliao/ShopeeWorkspace/demoWorkspace/rollup-axiosCopy the code
//main.ts
import test from 'rollup-axios-test';

test(a);Copy the code

Run the target project and an error is reported

[HMR] Waiting forupdate signal from WDS... index.mjs? 395a:1 Uncaught ReferenceError: global is not defined ateval(index.mjs? 395a:1) at Module... /.. /demoWorkspace/rollup-axios/dist/index.mjs (app.js:915) at __webpack_require__ (app.js:767) at fn (app.js:130) ateval(main.ts:18) at Module.. /src/main.ts (app.js:5423) at __webpack_require__ (app.js:767) at fn (app.js:130) at Object.1 (app.js:5509) at __webpack_require__ (app.js:767)Copy the code

Packing failed!

Let’s switch to the FETCH API and repackage

// src/index.ts
import axios from "axios";

async function testRollup() {
  console.log("test");
  // await axios.get("");

  const response = await fetch("", {
    method: "GET"
  });

  await response.text();
}

export default testRollup;
Copy the code

Without an error, let’s use the FETCH API instead.

If you use jEST test code, you can use jest-fetch.

Can’t the Rollup package support Axios? The answer is wrong. Look at an issue.

I saw that some students abandoned Axios and changed to FETCH like me, but there was a better solution.

Rollup will need some tweaks if we want Axios working and bundled successfully. Without the tweaks the Rollup bundle will be interrupted with errors caused by Axios.

Adding a small entry on the Axios README.md will spare a few hours of Googling desperate solutions.

We’ll need to add the below to the Rollup configuration:

// package.json
"rollup-plugin-node-resolve": "3.0"."rollup-plugin-json": "2.3"
Copy the code
// Rollup configuration
plugins: [
    rollupNodeResolve({ jsnext: true, preferBuiltins: true, browser: true }),
    rollupJson(),
    ...
]
Copy the code

Let’s switch to the following configuration

"use strict";

const commonjs = require("rollup-plugin-commonjs");
const resolve = require("rollup-plugin-node-resolve");

const babel = require("rollup-plugin-babel");
const { terser } = require("rollup-plugin-terser");
const json = require("rollup-plugin-json");

const inputOptions = {
  plugins: [
    resolve({ jsnext: true, preferBuiltins: true, browser: true }),
    commonjs({
      browser: true
    }),
    babel({
      exclude: ["node_modules/**"],
      runtimeHelpers: true
    }),
    terser(),
    json()
  ]

};

const outputOptions = {
  exports: "named"
};

module.exports = { inputOptions, outputOptions };

Copy the code

Re-enable axios in SRC /index.ts and run the package command.

> [email protected] build: umd/Users/leiliao ShopeeWorkspace/demoWorkspace/rollup - axios > cross - env TARGET = umd node build/index.js node-resolve: setting options.jsnext is deprecated, please override options.mainFields insteadCopy the code

It will run successfully at this point, but options.jsnext is deprecated, so let’s look at the rollup-plugin-node-resolve documentation

      mainFields: ['module'.'main'], // Default: ['module'.'main']

      // DEPRECATED: use "mainFields" instead
      // use "module" field for ES6 module if possible
      module: true, // Default: true

      // DEPRECATED: use "mainFields" instead
      // use "jsnext:main" if possible
      // legacy field pointing to ES6 module in third-party libraries,
      // deprecated in favor of "pkg.module":
      // - see: https://github.com/rollup/rollup/wiki/pkg.module
      jsnext: true,  // Default: false

      // DEPRECATED: use "mainFields" instead
      // use "main" field or index.js, even if itNot an ES6 module // (needs to be converted from CommonJS to ES6) // -- see https://github.com/rollup/rollup-plugin-commonjs main: true, // Default: true // some package.json files have a "browser" field which specifies // alternative files to load for people bundling for the browser. If // that's you, either use this option or add "browser" to the
      // "mainfields" option, otherwise pkg.browser will be ignored
      browser: true,  // Default: false
Copy the code

Modify the configuration as follows:

resolve({ mainFields: ["jsnext"."preferBuiltins"."browser"]}),Copy the code

Package, get a clean console, use Axios successfully.

The source code

rollup-axios

conclusion

When you encounter problems, you can not worry about solving them immediately. You can think about them first, then precipitate them, and finally do them. The efficiency will be much faster.