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

modules/index.js should re-export tslib.es6.js instead of tslib.js #143

Open
schickling opened this issue Jan 14, 2021 · 22 comments · May be fixed by #171
Open

modules/index.js should re-export tslib.es6.js instead of tslib.js #143

schickling opened this issue Jan 14, 2021 · 22 comments · May be fixed by #171

Comments

@schickling
Copy link

schickling commented Jan 14, 2021

Unless I'm misunderstanding something, I'd expect modules/index.js to re-export ../tslib.es6.js instead of ../tslib.js.

https://github.com/microsoft/tslib/blob/master/modules/index.js#L1

I'm basing my statement on the understanding that exports['.']['import'] should point to some "modern" code:

https://github.com/microsoft/tslib/blob/master/package.json#L29-L34

(The reason I'm opening this issue is that I'm facing some problem in combination with Vite which is based on ESM.)

@yyx990803
Copy link

yyx990803 commented Jan 20, 2021

@DanielRosenwasser would love an eye on this.

From Vite resolver's perspective, module is a non-standard condition in exports, so it resolves to the import condition... which points to an ESM file that imports a UMD file (!!!). This does work in Node.js because Node allows ESM to import commonjs files... however for a native-ESM dev server like Vite, it assumes entries specified by the import condition to only contain valid ESM all the way through.

On the other hand, why doesn't the import condition simply point to tslib.es6.js? What is the point of having the modules/index.js indirection?

This can be fixed on Vite's front by also checking the module condition in exports field, but that is technically non-standard :/

@wiesson
Copy link

wiesson commented Sep 7, 2021

Any updates to this?

I'm currently trying to understand whats wrong, but I have this error in my sveltekit project:

 > .svelte-kit/output/server/app.js:26097:14: warning: Using direct eval with a bundler is not recommended and may cause problems (more info: https://esbuild.github.io/link/direct-eval)
    26097 │     var mod = eval("quire".replace(/^/, "re"))(moduleName);
          ╵               ~~~~

 > .svelte-kit/output/server/app.js:41:7: error: No matching export in "node_modules/tslib/modules/index.js" for import "default"
    41 │ import require$$0$4, { __extends, __assign, __values, __read, __awaiter, __generator, __spreadArray, __rest } from "tslib";
       ╵        ~~~~~~~~~~~~

> Build failed with 1 error:
.svelte-kit/output/server/app.js:41:7: error: No matching export in "node_modules/tslib/modules/index.js" for import "default"
Error: Build failed with 1 error:

@milky2028
Copy link

@wiesson Have you been able to figure this out yet? I'm getting the same error. Haven't been able to find anything that fixes it, include aliasing in svelte.config.js to tslib/tslib.es6.js.

@wiesson
Copy link

wiesson commented Sep 28, 2021

@wiesson Have you been able to figure this out yet? I'm getting the same error. Haven't been able to find anything that fixes it, include aliasing in svelte.config.js to tslib/tslib.es6.js.

Unfortunately not :/ I'm also not sure, if its tslib itself or another extension. Somehow deleting .svelte-kit, node_modules and the lock file "solved" my problem without understanding why. But it sometimes occurs every now and then.

@samuba
Copy link

samuba commented Oct 2, 2021

Have the same problem with sveltekit build in adapter-vercel phase.
I was able to narrow it done to one import that is causing this: import { serverTimestamp } from "firebase/firestore"; (Firestore 9)
@wiesson's delete procedure did not help.

I hack-fixed this by running this script before executing npm run build:

import fs from 'fs'
try {
    const filePath = "node_modules/@firebase/firestore/package.json"
    fs.writeFileSync(filePath, fs.readFileSync(filePath, 'utf8').replace(
        `"node": "./dist/index.node.cjs.js",`, 
        `"node": "./dist/index.esm2017.js",`
    ))
    console.log("fixed vercel adapter")
} catch (err) {
    console.error("error: fixing vercel adapter", err)
}

@benterova
Copy link

Have the same problem with sveltekit build phase adapter-vercel. I was able to narrow it done to one import that is causing this: import { serverTimestamp } from "firebase/firestore"; (Firestore 9) @wiesson's delete procedure did not help.

I hack-fixed this by running this script before executing npm run build:

import fs from 'fs'
try {
    const filePath = "node_modules/@firebase/firestore/package.json"
    fs.writeFileSync(filePath, fs.readFileSync(filePath, 'utf8').replace(
        `"node": "./dist/index.node.cjs.js",`, 
        `"node": "./dist/index.esm2017.js",`
    ))
    console.log("fixed vercel adapter")
} catch (err) {
    console.error("error: fixing vercel adapter", err)
}

This worked for me as well, although would love to see this fixed for real.

@wiesson
Copy link

wiesson commented Oct 5, 2021

I think this issue is related, isn't it? -> firebase/firebase-js-sdk#5499

@evil-su, could you share your findings so that the firebase team could fix it? :)

@wiesson
Copy link

wiesson commented Oct 5, 2021

https://github.com/firebase/firebase-js-sdk/pull/5532/files

This looks promising 🎉

@orta
Copy link
Contributor

orta commented Oct 14, 2021

Switching to use tslib.es6.js fails to run in the esm-node-native test case in the repo, happy to have a vite test case in here (we already have snowpack for example) but any changes should need to be backwards compatible .

@milky2028
Copy link

I had to do this for firestore/lite as well in order to get it to work.

import { readFile, writeFile } from 'fs/promises';

const importJson = async (path) => JSON.parse(await readFile(new URL(path, import.meta.url)));

const path = 'node_modules/@firebase/firestore/package.json';
const pkg = await importJson(path);
pkg.exports['.'].node = './dist/index.esm2017.js';
pkg.exports['./lite'].node = './dist/lite/index.browser.esm2017.js';

await writeFile(new URL(path, import.meta.url), JSON.stringify(pkg));

console.log('Successfully fixed imports.');

@antongolub
Copy link

antongolub commented Nov 3, 2021

@orta,

Can we at least just change re-export to import * as tslib from '../tslib.js'; or smth like that?
This fixes missed default export in esm mode (NODE_OPTIONS=--experimental-vm-modules)

SyntaxError: The requested module '../tslib.js' does not provide an export named 'default'

@jogibear9988
Copy link

same issue here: #161

@noahbald
Copy link

noahbald commented Nov 21, 2021

Have the same problem with sveltekit build in adapter-vercel phase. I was able to narrow it done to one import that is causing this: import { serverTimestamp } from "firebase/firestore"; (Firestore 9) @wiesson's delete procedure did not help.

I hack-fixed this by running this script before executing npm run build:

import fs from 'fs'
try {
    const filePath = "node_modules/@firebase/firestore/package.json"
    fs.writeFileSync(filePath, fs.readFileSync(filePath, 'utf8').replace(
        `"node": "./dist/index.node.cjs.js",`, 
        `"node": "./dist/index.esm2017.js",`
    ))
    console.log("fixed vercel adapter")
} catch (err) {
    console.error("error: fixing vercel adapter", err)
}

I've been getting the same issue with other packages when using sveltekit/vite - I've adapted your idea to fix it at the source by adding a default export to tslib.

This seems to fix things for me.

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

try {
  const filePath = path.resolve('./node_modules/tslib/modules/index.js')
  console.log('fixing tslib export', filePath)
  let file = fs.readFileSync(filePath, 'utf8')
  if (!file.includes('export default')) {
    file += '\nexport default tslib;\n'
  }
  fs.writeFileSync(filePath, file)
} catch (err) {
  console.error('error: fixing tslib export', err)
}

It's not ideal so I'd love to see this fixed on tslib's end or from sveltekit/vite (not too sure which one is causing the issue at hand)

@rbuckton
Copy link
Member

rbuckton commented Feb 8, 2022

NodeJS does not consider tslib.es6.js to be an ES Module because it has a .js extension. tslib.es6.js predates NodeJS's ESM support and wasn't really designed for it. NodeJS does treat modules/index.js as an ES Module due to the package.json in that folder containing { "type": "module" }.

Rather than have modules/index.js contain a third copy of the helpers that we need to maintain, we chose to have it re-export an existing set of helpers. We can't re-export tslib.es6.js, since that would still be treated as a CommonJS module by Node and would error on the use of the export keyword. Instead we chose to re-export tslib.js, which is a valid CommonJS module.

The only alternative I can think of is to move the contents of tslib.es6.js into modules/index.js, and change tslib.es6.js to just export * from "./modules/index.js";. That keeps the duplication to a minimum as its still only two copies to maintain.

@rbuckton rbuckton linked a pull request Feb 8, 2022 that will close this issue
@rbuckton
Copy link
Member

Is this still an issue in Vite? I added a test locally using vite and it seems to import tslib just fine as is.

@rbuckton
Copy link
Member

I've added a test for vite@2.8.0 in #172 and I'm not seeing the error that's being described in this issue. @schickling (or anyone else experiencing this), can you review the PR and let me know if I'm missing something in that test that would help me reproduce the issue you are describing?

@thescientist13
Copy link

If it helps, the use case that led me here was trying to work with Material Web Components, in my case was just testing out @material/mwc-button and using ESM from the browser via import map.

The dependency chain is pretty short:

  1. @material/mwc-button has a direct dependency on tslib
  2. To resolve tslib for ESM, you hit the issue here, either resolving exports or module in package.json (in my case I am following the export map)

@rbuckton
Copy link
Member

If it helps, the use case that led me here was trying to work with Material Web Components, in my case was just testing out @material/mwc-button and using ESM from the browser via import map.

Would import maps give you the ability to remap tslib as well?

@thescientist13
Copy link

thescientist13 commented Feb 11, 2022

Would import maps give you the ability to remap tslib as well?

Yes, if hand rolling the import map as the 1st party, this would be doable.

But similar to the Vite use case, the files to resolve (and the import map) are being determined programmatically, and so is entirely based on what the dependencies themselves define via their package.json. So this fix would be very useful to all ecosystem tools looking to operate against the spec in NodeJS.

@rbuckton
Copy link
Member

If it helps, the use case that led me here was trying to work with Material Web Components, in my case was just testing out @material/mwc-button and using ESM from the browser via import map.

The dependency chain is pretty short:

  1. @material/mwc-button has a direct dependency on tslib
  2. To resolve tslib for ESM, you hit the issue here, either resolving exports or module in package.json (in my case I am following the export map)

Can you provide a more detailed repro?

@thescientist13
Copy link

Yeah, you can see this branch where I am trying to integrate MWC and hitting this issue. Following the ESM spec would be great here, so thanks in advance for taking a look. 🙏

@JavascriptMick
Copy link

JavascriptMick commented Dec 11, 2023

I had a related issue. In my case, my site is deployed on Netlify and I have a transient dependency on tslib from "@azure/ai-form-recognizer": "^5.0.0",.

After trying a bunch of different things that didn't work, I found this worked.

  1. Added an explicit import for tslib
    "tslib": "^2.6.2",

  2. added a fix (hack) script in my repo
    build_scripts/fix_tslib_node.mjs

import fs from 'fs'
try {
  const filePath = "node_modules/tslib/package.json"
  fs.writeFileSync(filePath, fs.readFileSync(filePath, 'utf8').replace(
    `"node": "./modules/index.js",`,
    `"node": "./tslib.es6.mjs",`
  ))
  console.log("node setting for tslib fixed (hacked)")
} catch (err) {
  console.error("error: fixing node setting for tslib", err)
}
  1. changed Build and Deployment -> Continuous Deployment -> Build Settings -> Build command
    node build_scripts/fix_tslib_node.mjs && npm run build

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

Successfully merging a pull request may close this issue.