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

fix(dev): transform import for commonjs dependencies #837

Merged
merged 23 commits into from Nov 24, 2020

Conversation

csr632
Copy link
Member

@csr632 csr632 commented Sep 20, 2020

...so that user can do named import from them.

This is a different approach from pull/825 to fix #720

In the optimze step, it collect information about optimized deps (whether it is cjs).
When rewriting import during vite serve, if the importee is a "optimized cjs deps", it will get named import from the default export.
For example,

import React, { useState, createContext } from 'react'

will become

import $viteCjsImport1_react from "/@modules/react.js";
const React = $viteCjsImport1_react;
const useState = $viteCjsImport1_react["useState"];
const createContext = $viteCjsImport1_react["createContext"];

It is better than #825 because it doesn't require users to manually specific export names.

@pd4d10
Copy link
Contributor

pd4d10 commented Sep 22, 2020

Does this feature deprecate optimizeDeps.auto config? It seems generate different results if optimizeDeps.auto is false.

@csr632
Copy link
Member Author

csr632 commented Sep 25, 2020

Does this feature deprecate optimizeDeps.auto config? It seems generate different results if optimizeDeps.auto is false.

optimizeDeps.auto is used to controll "whether run vite optimize automatically on server start". It is not relavent to this PR. If you have encountered bugs, please provide a reproduction. @pd4d10

@csr632
Copy link
Member Author

csr632 commented Sep 30, 2020

@underfin @antfu
Could we merge this?

@remorses

This comment has been minimized.

@csr632
Copy link
Member Author

csr632 commented Oct 14, 2020

I have another approach that would be interesting to investigate before merging this PR, if you agree i can open another PR with the approach below:

Instead of rewriting imports we could use a fake entrypoint to pass to rollup that reexports (with ESM exporting syntax) from the commonjs module, this way rollup generate valid ESM esports and not only a default export.

For example in case of react we pass to rollup an entrypoint with the code

export { useState, useEffect, ... } from 'react'
export * from 'react'
import defaultExport from 'react'
export default defaultExport

Rollup processes this file and outputs valid ESM exports

PS. Snowpack does this to allow for named imports from cjs modules
To detect the named exports of the commonjs module we can use https://github.com/guybedford/cjs-module-lexer

This is exactly what my previous PR was doing.
Checkout this comment for why that is deprecated.

@remorses
Copy link
Contributor

Yes you are right, this is definitely a better approach

@underfin
Copy link
Member

@csr632 Can you have a try with rollup/plugins#604 instead of cjs-module-lexer

@remorses
Copy link
Contributor

remorses commented Oct 15, 2020

@underfin I would like to migrate the optimizer to esbuild after they add plugins support, can we try not couple the optimizer too much to rollup?

Also, the use of es-module-lexer is better imho, we detect if the user is using named imports, if yes and there are no named imports in the module then they are extracted from the default import

Edit: forget about it, i will just use es-module-lexer in the esbuild version

@antfu
Copy link
Member

antfu commented Oct 15, 2020

@knightly-bot build this

@kmacute
Copy link

kmacute commented Oct 20, 2020

Thanks for this

@Rainmen-xia
Copy link

mark

@kmacute
Copy link

kmacute commented Oct 27, 2020

using rc8
image

rollback to this pr fixed the issue

waiting for this pr to be merged

@csr632
Copy link
Member Author

csr632 commented Oct 27, 2020

We should wait for rollup/plugins#604 to be published before we can merge this PR. So I am turning this PR to draft.

The upstream rollup plugins have been released. Now this PR is ready to be merged! @yyx990803

@csr632 csr632 marked this pull request as ready for review October 27, 2020 06:59
package.json Show resolved Hide resolved
@csr632
Copy link
Member Author

csr632 commented Nov 23, 2020

@underfin @yyx990803 @antfu
This PR is ready to be merged. Let me help if there is anything blocking this PR. Thanks!

@zheeeng
Copy link
Contributor

zheeeng commented Sep 7, 2021

Any solution for reexporting commonjs module?

// a.ts
export * from 'moduleTranspiledToCommonjs'
// b.ts
import { foo } from './a'

will produce warning:

Uncaught SyntaxError: The requested module '/a.ts' does not provide an export named 'foo'

@SamuelScheit
Copy link

I have the same error as @zheeeng. Any updates on this?

@csr632
Copy link
Member Author

csr632 commented Dec 27, 2022

It may become too complicated if we support re-exporting cjs. What is the expected behavior of this and how to implement it? 🤔

// a.ts
export * from 'moduleTranspiledToCommonjs1'  // may contain `module.exports.foo = 'value1'`
export * from 'moduleTranspiledToCommonjs2'  // may contain `module.exports.foo = 'value2'`
export * from 'someESModule'  // may contain `export const foo = 'value3'`. It may also contain cjs re-export
// b.ts
import { foo } from './a'
console.log(foo);

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 this pull request may close these issues.

Support named exports in cjs libraries for optimizer