Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECMAScript Module (ESM) support #27

Open
robaca opened this issue Dec 22, 2021 · 0 comments
Open

ECMAScript Module (ESM) support #27

robaca opened this issue Dec 22, 2021 · 0 comments

Comments

@robaca
Copy link

robaca commented Dec 22, 2021

Hi,

please add support for isomorphic-loader for module type projects (and hybrid variants).

We are currently facing two issues here:

(1) extendRequire does not work for ES modules. I played around writing our own ESM loader (only works on Node >=16.12):

import fs from 'fs'
import path from 'path'
import assert from 'assert'

const isomorphicLoaderConfig = JSON.parse(await fs.promises.readFile(path.join(process.cwd(), '.isomorphic-loader-config.json'), 'utf-8'))
assert.ok(isomorphicLoaderConfig?.assetsFile, 'please run "yarn build:staticResources" before running "yarn build:staticPages"')
const isomorphicAssets = JSON.parse(await fs.promises.readFile(isomorphicLoaderConfig.assetsFile, 'utf-8'))

const EXTENSIONS = ['.svg', '.jpg', '.png']

export async function resolve(specifier, context, defaultResolve) {
    const { parentURL = null } = context
    if (EXTENSIONS.some((ext) => specifier.endsWith(ext))) {
        const url = parentURL ? new URL(specifier, parentURL).href : new URL(specifier).href
        return { url }
    }
    return defaultResolve(specifier, context)
}

export async function load(url, context, defaultLoad) {
    if (EXTENSIONS.some((ext) => url.endsWith(ext))) {
        const assetPath = Object.keys(isomorphicAssets.marked).find((asset) => url.endsWith(asset))
        if (assetPath) {
            return {
                format: 'json',
                source: `"/our-prefix/${isomorphicAssets.marked[assetPath]}"`,
            }
        }
        throw new Error(`Did not find asset ${url} in isomorphic-assets.json`)
    }
    return defaultLoad(url, context, defaultLoad)
}

A hybrid solution would mean to also support CJS dependencies which still use require.

(2) Maybe webpack 4 or TypeScript related, but the isomorphic-assets.json is missing the entries in marked that are direct dependencies of es module files. I checked the webpack-plugin.js and the top level modules list traversed by this snippet is not containing the relevant modules. Instead they can be found in nested modules:

      const marked = stats.modules.reduce((acc, m) => {
        sigIdx = m.identifier.indexOf(loaderSig);
        if (sigIdx >= 0 && m.assets && m.assets.length > 0) {
          const n = posixify(removeCwd(m.identifier.substr(sigIdx + loaderSig.length), true));
          acc[n] = m.assets[m.assets.length - 1];
        }

I do not know enough of the internals of webpack to propose a fix here - maybe it's already a bug in the ts-loader or file-loader...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant