代码之家  ›  专栏  ›  技术社区  ›  BlueWater86

解析从具有汇总的URL导入的ES6模块

  •  1
  • BlueWater86  · 技术社区  · 6 年前

    import { authInstance } from "http://auth-microservice/js/authInstance.js"
    

    我正在接近一个发布周期,并且已经开始沿着我通常的路径使用rollup绑定到IIFEs。Rollup似乎不支持从url导入es6模块,我认为应该这样做,因为规范中允许这样做:(

    要从中导入的模块。这通常是包含模块的.js文件的相对或绝对路径名。某些绑定器可能允许或要求使用扩展;请检查您的环境。只允许单引号和双引号字符串。( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import )

    1 回复  |  直到 6 年前
        1
  •  2
  •   BlueWater86    6 年前

    我不得不从这一点上快速前进,所以最后只写了一个汇总插件的框架。我仍然觉得解析绝对路径应该是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 })
                }
            }
        }
    }