【发布时间】:2020-03-05 15:54:00
【问题描述】:
我有一个分布式系统,所有的 JS 文件都是通过 HTTP 公开的。所以一个普通的模块应该是这样的:
http://example.com/path/to/main.js
import * as core from 'http://local.example.com/path/to/core.js';
import * as redux from 'http://cdn.example.com/redux.js@version';
// code
export default {
...
}
因此,每次导入都将使用系统的本地资源或可能使用 CDN 的远程可用资源。
想到当我运行 webpack 时,我得到了这个错误:
尝试解析具有此类内容的本地生成文件:
import * as main from 'http://example.com/path/to/main.js';
./src/index.js 中的错误未找到模块:错误:无法解析 '/home/.../index.js'中的'http://example.com/path/to/main.js'
是否可以告诉 webpack 获取 url 并将它们包含在 bundle 中...虽然打包 cdn url 目前并不是什么大问题,但如果我可以简单地忽略具有特定含义的那些,我会很高兴网址。
认为能够远程捆绑所有 http:// 定位的文件将是一个好的开始。
此外,任何链接到其他资源的远程资源也应该递归加载远程链接的资源。
这是我当前的 webpack 配置(这里没什么可看的):
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
]
},
};
编辑:读了一点之后,我开始写一个解析器,但现在我又卡住了:
const path = require('path');
const fetch = require('node-fetch');
const url = require('url')
const fs = require('promise-fs');
const sha1 = require('sha1')
class CustomResolver {
async download_save(request, resolveContext) {
console.log(request, resolveContext)
var target = url.parse(request.request)
var response = await fetch(request.request)
var content = await response.text()
try {
await fs.stat('_remote')
} catch(exc) {
await fs.mkdir('_remote')
}
var filename = `${sha1(request.request)}.js`
var file_path = `_remote/${filename}`
await fs.writeFile(file_path, content)
var abs_path = path.resolve(file_path)
var url_path = `${target.protocol}://${target.hostname}/`
var obj = {
path: abs_path,
request: request.request,
query: '',
}
console.log(`${request.request} saved to ${abs_path}`)
return obj
}
apply(resolver) {
var self = this
const target = resolver.ensureHook("resolved")
resolver.getHook("module")
.tapAsync("FetchResolverPlugin", (request, resolveContext, callback) => {
self.download_save(request, resolveContext)
.then((obj) => resolver.doResolve(target, obj, resolveContext, callback))
.catch((err) => {
console.log(err)
callback()
})
})
}
}
它目前确实获取以 https:// 开头的 url,但似乎很难解析相对于 http 资源的 url。例如
ERROR in _remote/88f978ae6c4a58e98a0a39996416d923ef9ca531.js
Module not found: Error: Can't resolve '/-/@pika/polyfill@v0.0.3/dist=es2017/polyfill.js' in '_remote/'
@ _remote/88f978ae6c4a58e98a0a39996416d923ef9ca531.js 25:0-58
@ _remote/f80b922b2dd42bdfaaba4e9f4fc3c84b9cc04fca.js
@ ./src/index.js
它看起来并没有尝试解析已解析文件的相对路径。有没有办法告诉解析器尝试解决所有问题?
【问题讨论】:
-
为什么不用node.js脚本下载文件然后打包到本地?
-
@quirimmo 因为我要编写自己的捆绑程序?每个资源都可以链接到其他远程存储的资源。获取它们意味着捆绑器仍然无法加载链接到远程资源的导入。我必须手动重写文件以将 http url 更改为本地的。
-
不,您只需要使用自定义解析器,而无需更改代码中的导入:
-
@quirimmo 我猜是这样,这就是我提出这个问题的原因。如果我知道如何使用 WebPack 做到这一点,我就不会问了!
-
@quirimmo here 我开始编写解析器,但它无法解析 http 资源的绝对或相对路径。
标签: javascript webpack bundle distributed-system