以前的文章有提到 npm 模塊的組成和發佈,最近手頭有一個第三方 sdk 的開發,使用 lerna 進行 npm 包的維護,使用 ts 進行開發和測試。vue
固然 sdk 的打包工具使用了 rollup,這裏不對 rollup 和 webpack 進行介紹和比較,vue 和 react 也是使用 rullup ,社區有一大推這方面內容的介紹和教程,下面咱們開始細說當 rollup 碰見 axios 時發生的一些故事。node
目錄結構以下:react
╰─➤ tree -L 2 -I node_modules
.
├── babel.config.js
├── build
│ ├── index.js
│ └── rollup.config.js
├── index.ts
├── package-lock.json
├── package.json
├── src
│ └── index.ts
└── tsconfig.json
複製代碼
// package.json
{
"name": "rollup-test",
"version": "0.1.0",
"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": "^6.0.1",
"typescript": "^3.1.6"
},
"devDependencies": {
"axios": "^0.19.0"
}
}
複製代碼
// 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 };
複製代碼
// src/index.ts
import axios from "axios";
async function testRollup() {
console.log("test");
await axios.get("");
}
export default testRollup;
複製代碼
運行 npm run build 獲得以下結果 :webpack
╰─➤ npm run build
> rollup-axios-test@1.0.0 build /Users/leiliao/ShopeeWorkspace/demoWorkspace/rollup-axios
> tsc && node build/index.js
'http' is imported by node_modules/axios/lib/adapters/http.js, but could not be resolved – treating it as an external dependency
'https' is imported by node_modules/axios/lib/adapters/http.js, but could not be resolved – treating it as an external dependency
'url' is imported by node_modules/axios/lib/adapters/http.js, but could not be resolved – treating it as an external dependency
'zlib' is imported by node_modules/axios/lib/adapters/http.js, but could not be resolved – 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-redirects/index.js, but could not be resolved – treating it as an external dependency
'http' is imported by node_modules/follow-redirects/index.js, but could not be resolved – treating it as an external dependency
'https' is imported by node_modules/follow-redirects/index.js, but could not be resolved – treating it as an external dependency
'assert' is imported by node_modules/follow-redirects/index.js, but could not be resolved – 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-redirects/index.js, but could not be resolved – 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 dependency
複製代碼
根據以上錯誤修改 rollUp 配置,添加 external 字段ios
"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 };
複製代碼
打包結果以下git
> ts-vuex-demo@0.1.0 build:umd /Users/leiliao/ShopeeWorkspace/demoWorkspace/rollup-axios
> cross-env TARGET=umd node build/index.js
No name was provided for external module 'http' in output.globals – guessing 'http'
No name was provided for external module 'https' in output.globals – guessing 'https'
No name was provided for external module 'url' in output.globals – guessing 'url'
No name was provided for external module 'assert' in output.globals – guessing 'assert'
No name was provided for external module 'stream' in output.globals – guessing 'stream'
No name was provided for external module 'tty' in output.globals – guessing 'tty'
No name was provided for external module 'util' in output.globals – guessing 'util'
No name was provided for external module 'os' in output.globals – guessing 'os'
No name was provided for external module 'zlib' in 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
複製代碼
在打包 umd 格式的代碼時出現提示,安裝 rollup-plugin-node-builtins,並在 rollup 中使用。es6
"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 };
複製代碼
打包獲得以下信息github
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
複製代碼
爲啥用官方提示的工具也不行呢?讓咱們試一下打出來的包是否能使用(筆者一開始覺得這只是 warnning),咱們使用 npm link 運行當前項目web
╰─➤ npm link
audited 3216 packages in 6.82s
found 26 moderate severity vulnerabilities
run `npm audit fix` to fix them, or `npm audit` for details
/Users/leiliao/.nvm/versions/node/v10.15.3/lib/node_modules/rollup-test -> /Users/leiliao/....../demoWorkspace/rollup-axios
複製代碼
而後在一個新項目中引用它vuex
╰─➤ 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-axios
複製代碼
//main.ts
import test from 'rollup-axios-test';
test();
複製代碼
運行目標項目,發現報錯
[HMR] Waiting for update signal from WDS...
index.mjs?395a:1 Uncaught ReferenceError: global is not defined
at eval (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)
at eval (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)
複製代碼
說明打包失敗!
咱們換用 fetch api ,並從新弄打包
// 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;
複製代碼
不出現報錯,那咱們仍是使用 fetch api 吧。
若是使用了 jest 測試代碼 ,可使用 jest-fetch.
難道 rollup 打包不能支持 axios 嗎 ? 答案是錯誤的。看一條 issue 。
看到有同窗跟我同樣 棄用了 axios ,改用 fetch ,可是更好的解決辦法。
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"
複製代碼
// Rollup configuration
plugins: [
rollupNodeResolve({ jsnext: true, preferBuiltins: true, browser: true }),
rollupJson(),
...
]
複製代碼
咱們改用配置以下
"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 };
複製代碼
在 src/index.ts 中從新啓用 axios,運行打包命令。
> rollup-test@0.1.0 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 instead
複製代碼
這時候已經可以成功運行了,可是 options.jsnext is deprecated , 因此咱們查看一下 rollup-plugin-node-resolve 的文檔
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 it's not 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
複製代碼
修改配置以下:
resolve({ mainFields: ["jsnext", "preferBuiltins", "browser"] }),
複製代碼
打包,獲得一個乾淨的控制檯,成功使用 axios。
遇到問題其實能夠不着急立刻解決,能夠先思考,再沉澱,最後動手去作,效率會快不少。