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

expression replacement - replace process.env.NODE_ENV #1330

Closed
hyf0 opened this issue Nov 15, 2023 · 11 comments
Closed

expression replacement - replace process.env.NODE_ENV #1330

hyf0 opened this issue Nov 15, 2023 · 11 comments
Assignees
Labels
A-transformer Area - Transformer / Transpiler P-high Priority - High

Comments

@hyf0
Copy link
Contributor

hyf0 commented Nov 15, 2023

What's expression replacement

There's need for users that is replacing some expression with another expression in source code.

A typical use case is to replace process.env.NODE_ENV to "production".

Input with typical config

export default {
  input: 'src/index.js',
  output: {
    dir: 'output',
    format: 'cjs',
  },
  plugins: [
    define({
      replacements: {
        'process.env.NODE_ENV': '"production"',
      },
    }),
  ],
}
console.log(process.env.NODE_ENV)

would be transformed to

console.log("production")

Thoughts

The processes of this feature in general are

  1. parse the source code to ast
  2. parse process.env.NODE_ENV in 'process.env.NODE_ENV': '"production"' to Expression, which we called it target now.
  3. parse "production" in 'process.env.NODE_ENV': '"production"' to Expression, which we called it replacement now.
  • The Expression should stored in the same arena that used in step1. How we do this?
  • Oxc need to provide a method to parse something to an Expression.
  1. Walk through the ast, in VisitMut#visit_expression , if some expr == target, then std::mem::replace(&mut expr, replacement.clone()).
  • expr == target is a problem, this comparison should ignore the Span, SymbolId and ReferenceId
  • replacement.clone() doesn't seem to works.
@Boshen
Copy link
Member

Boshen commented Nov 15, 2023

In what stages does esbuild and rollup do this? These features should be builtin features provided by oxc.

Oxc already has a work-in-proess transformer and minimizer, ideally we just have to add these features into these two AST passes and let the bundler use these features.

@hyf0
Copy link
Contributor Author

hyf0 commented Nov 15, 2023

In what stages does esbuild and rollup do this? These features should be builtin features provided by oxc.

That's tricky to say. Rollup support it using the plugin, so rollup itself doesn't provide this feature.

These features should be builtin features provided by oxc.

I think so. But the problems I mentioned above would still exist.

@Boshen
Copy link
Member

Boshen commented Nov 15, 2023

This is why I am interested in how esbuild and rollup solves these problems, even it's inside a plugin.

@hyf0
Copy link
Contributor Author

hyf0 commented Nov 15, 2023

This is why I am interested in how esbuild and rollup solves these problems, even it's inside a plugin.

It's quite complex, which makes it a challenge for writing it down. Maybe we could discuss it using voice chat.

@Boshen Boshen changed the title A few thoughts on implementing expression replacement expression replacement - replace process.env.NODE_ENV Dec 6, 2023
@Boshen Boshen self-assigned this Feb 20, 2024
@Boshen Boshen added P-high Priority - High A-transformer Area - Transformer / Transpiler labels Feb 20, 2024
@Boshen
Copy link
Member

Boshen commented May 8, 2024

I think I can figure this out if we reduce the scope to inlining process.env.x and identifiers, as shown in https://github.com/swc-project/swc/blob/94da1241720ed029bc41b6068a9267e2c86347d0/crates/swc_ecma_transforms_optimization/src/inline_globals.rs

@Boshen
Copy link
Member

Boshen commented May 8, 2024

@hyf0 Can you give me test case in Rolldown so I can test the whole thing end to end?

@hyf0
Copy link
Contributor Author

hyf0 commented May 8, 2024

@hyf0 Can you give me test case in Rolldown so I can test the whole thing end to end?

I could give one or two cases, but I don't have a test list for this feature.


Maybe the tests of swc could be a start: https://github.com/swc-project/swc/blob/94da1241720ed029bc41b6068a9267e2c86347d0/crates/swc_ecma_transforms_optimization/src/inline_globals.rs#L252-L319.

@hyf0
Copy link
Contributor Author

hyf0 commented May 8, 2024

if we reduce the scope to inlining process.env.x and identifiers

Yeah. This could be start for implementing expression replacement, but in the end we gonna need a general-used expression replacement feature that could almost replace everything not only process.env.xxx.

@hyf0
Copy link
Contributor Author

hyf0 commented May 8, 2024

@Boshen Boshen added this to the Transformer Milestone 1 milestone May 27, 2024
@Boshen
Copy link
Member

Boshen commented Jun 21, 2024

Skeleton is done in #3803, I'll port esbuild's behaviour and tests.

@Boshen Boshen closed this as completed Jun 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-transformer Area - Transformer / Transpiler P-high Priority - High
Projects
None yet
Development

No branches or pull requests

2 participants