使用 Rollup 解析从 URL 导入的 ES6 模块
Resolving an ES6 module imported from a URL with Rollup
从 ES6 模块中的 URL 导入是完全有效的,因此我一直在使用这种技术在位于不同 hosts/ports:[=13 的微服务之间重用模块=]
import { authInstance } from "http://auth-microservice/js/authInstance.js"
我即将发布一个发布周期,并开始使用 rollup 进行捆绑到 IIFE 的惯常路径。 Rollup 似乎不支持从 URLs 导入 es6 模块,我认为应该支持,因为这在规范中是允许的:(
module-name
The module to import from. This is often a relative or absolute path name to the .js file containing the module. Certain bundlers may permit or require the use of the extension; check your environment. Only single quotes and double quotes Strings are allowed. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
我已经在互联网上搜索了一个小时,但一无所获。有人见过类似于 rollup-plugin-node-resolve 的解析器来解析 URLs 中的模块吗?
我不得不从这里开始,所以最后只写了一个汇总插件的框架。我还是觉得解析绝对路径应该是rollup的一个核心特性。
已更新代码段
在相当长的一段时间里,我们一直在使用它来为我们的几个应用程序转换生产代码。
const fs = require('fs'),
path = require('path'),
axios = require("axios")
const createDir = path => !fs.existsSync(path) && fs.mkdirSync(path)
const mirrorDirectoryPaths = async ({ cacheLocation, url }) => {
createDir(cacheLocation)
const dirs = [], scriptPath = url.replace(/:\/\/|:/g, "-")
let currentDir = path.dirname(scriptPath)
while (currentDir !== '.') {
dirs.unshift(currentDir)
currentDir = path.dirname(currentDir)
}
dirs.forEach(d => createDir(`${cacheLocation}${d}`))
return `${cacheLocation}${scriptPath}`
}
const cacheIndex = {}
const writeToDiskCache = async ({ cacheLocation, url }) => {
//Write a file to the local disk cache for rollup to pick up.
//If the file is already existing use it instead of writing a new one.
const cached = cacheIndex[url]
if (cached) return cached
const cacheFile = await mirrorDirectoryPaths({ cacheLocation, url }),
data = (await axiosInstance.get(url).catch((e) => { console.log(url, e) })).data
fs.writeFileSync(cacheFile, data)
cacheIndex[url] = cacheFile
return cacheFile
}
const urlPlugin = (options = { cacheLocation }) => {
return {
async resolveId(importee, importer) {
//We importing from a URL
if (/^https?:\/\//.test(importee)) {
return await writeToDiskCache({ cacheLocation: options.cacheLocation, url: importee })
}
//We are importing from a file within the cacheLocation (originally from a URL) and need to continue the cache import chain.
if (importer && importer.startsWith(options.cacheLocation) && /^..?\//.test(importee)) {
const importerUrl = Object.keys(cacheIndex).find(key => cacheIndex[key] === importer),
importerPath = path.dirname(importerUrl),
importeeUrl = path.normalize(`${importerPath}/${importee}`).replace(":\", "://").replace(/\/g, "/")
return await writeToDiskCache({ cacheLocation: options.cacheLocation, url: importeeUrl })
}
}
}
}
此插件与以下配置一起适用于我:
https://github.com/mjackson/rollup-plugin-url-resolve
import typescript from "@rollup/plugin-typescript";
import urlResolve from "rollup-plugin-url-resolve";
export default {
output: {
format: "esm",
},
plugins: [
typescript({ lib: ["es5", "es6", "dom"], target: "es5" }),
urlResolve(),
],
};
显然你可以删除 TypeScript 插件。
从 ES6 模块中的 URL 导入是完全有效的,因此我一直在使用这种技术在位于不同 hosts/ports:[=13 的微服务之间重用模块=]
import { authInstance } from "http://auth-microservice/js/authInstance.js"
我即将发布一个发布周期,并开始使用 rollup 进行捆绑到 IIFE 的惯常路径。 Rollup 似乎不支持从 URLs 导入 es6 模块,我认为应该支持,因为这在规范中是允许的:(
module-name The module to import from. This is often a relative or absolute path name to the .js file containing the module. Certain bundlers may permit or require the use of the extension; check your environment. Only single quotes and double quotes Strings are allowed. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
我已经在互联网上搜索了一个小时,但一无所获。有人见过类似于 rollup-plugin-node-resolve 的解析器来解析 URLs 中的模块吗?
我不得不从这里开始,所以最后只写了一个汇总插件的框架。我还是觉得解析绝对路径应该是rollup的一个核心特性。
已更新代码段
在相当长的一段时间里,我们一直在使用它来为我们的几个应用程序转换生产代码。
const fs = require('fs'),
path = require('path'),
axios = require("axios")
const createDir = path => !fs.existsSync(path) && fs.mkdirSync(path)
const mirrorDirectoryPaths = async ({ cacheLocation, url }) => {
createDir(cacheLocation)
const dirs = [], scriptPath = url.replace(/:\/\/|:/g, "-")
let currentDir = path.dirname(scriptPath)
while (currentDir !== '.') {
dirs.unshift(currentDir)
currentDir = path.dirname(currentDir)
}
dirs.forEach(d => createDir(`${cacheLocation}${d}`))
return `${cacheLocation}${scriptPath}`
}
const cacheIndex = {}
const writeToDiskCache = async ({ cacheLocation, url }) => {
//Write a file to the local disk cache for rollup to pick up.
//If the file is already existing use it instead of writing a new one.
const cached = cacheIndex[url]
if (cached) return cached
const cacheFile = await mirrorDirectoryPaths({ cacheLocation, url }),
data = (await axiosInstance.get(url).catch((e) => { console.log(url, e) })).data
fs.writeFileSync(cacheFile, data)
cacheIndex[url] = cacheFile
return cacheFile
}
const urlPlugin = (options = { cacheLocation }) => {
return {
async resolveId(importee, importer) {
//We importing from a URL
if (/^https?:\/\//.test(importee)) {
return await writeToDiskCache({ cacheLocation: options.cacheLocation, url: importee })
}
//We are importing from a file within the cacheLocation (originally from a URL) and need to continue the cache import chain.
if (importer && importer.startsWith(options.cacheLocation) && /^..?\//.test(importee)) {
const importerUrl = Object.keys(cacheIndex).find(key => cacheIndex[key] === importer),
importerPath = path.dirname(importerUrl),
importeeUrl = path.normalize(`${importerPath}/${importee}`).replace(":\", "://").replace(/\/g, "/")
return await writeToDiskCache({ cacheLocation: options.cacheLocation, url: importeeUrl })
}
}
}
}
此插件与以下配置一起适用于我: https://github.com/mjackson/rollup-plugin-url-resolve
import typescript from "@rollup/plugin-typescript";
import urlResolve from "rollup-plugin-url-resolve";
export default {
output: {
format: "esm",
},
plugins: [
typescript({ lib: ["es5", "es6", "dom"], target: "es5" }),
urlResolve(),
],
};
显然你可以删除 TypeScript 插件。