web-infra-dev / rspack

The fast Rust-based web bundler with webpack-compatible API πŸ¦€οΈ
https://rspack.dev
MIT License
9.84k stars 569 forks source link

[Bug]: `import "binaryen"` throws error "'import.meta' cannot be used outside of module code" when minimize is on #6513

Closed xc2 closed 6 months ago

xc2 commented 6 months ago

System Info

  System:
    OS: macOS 14.5
    CPU: (12) arm64 Apple M2 Max
    Memory: 97.03 MB / 32.00 GB
    Shell: 3.7.1 - /opt/homebrew/bin/fish
  Binaries:
    Node: 20.12.2 - ~/.managed/n/bin/node
    Yarn: 1.22.21 - ~/.managed/n/bin/yarn
    npm: 10.5.0 - ~/.managed/n/bin/npm
    pnpm: 8.15.4 - ~/.managed/n/bin/pnpm
    bun: 1.0.34 - /opt/homebrew/bin/bun
    Watchman: 2024.03.18.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 124.0.6367.158
    Safari: 17.5
  npmPackages:
    @rspack/cli: ^0.6.3 => 0.6.5 
    @rspack/core: ^0.6.3 => 0.6.5 

Details

Code

import a from 'binaryen';

console.log(a);

Configuration

module.exports = {
  mode: "none",
  optimization: {
    // when minimize is on, importing binaryen will produce error "'import.meta' cannot be used outside of module code"
    minimize: true,
  },
}

Got


> rspack-repro@1.0.0 build:rspack /Users/kfll/Developer/rspack-repro-binaryen
> rspack -c rspack.config.js

ERROR in Γ— JavaScript parsing error: 'import.meta' cannot be used outside of module code.
   ╭─[4:1]
 4 β”‚  * SPDX-License-Identifier: Apache-2.0
 5 β”‚  */
 6 β”‚ var JC=(()=>{var vA=import.meta.url;return async fun...

Expected

There's type:"module" in binaryen/package.json so it should be considered as module code

More

This only happens when minimize is on

Reproduce link

https://github.com/xc2/rspack-repro-binaryen

Reproduce Steps

pnpm i
pnpm build:rspack | less
h-a-n-a commented 6 months ago

Try to enable module in SWC js minifier plugin.

xc2 commented 6 months ago

I've simplified the reproduction.

This problem occurs when importing a "module" package whose main file contains new URL("./", import.meta.url).

Both rspack and webpack will create an asset file xxx.js for the main file itself because of the statement new URL("./", import.meta.url) as documented: https://webpack.js.org/guides/asset-modules/#url-assets

Consider the foo example, the package foo has these two traits:

  1. there's new URL("./", import.meta.url) in foo/index.js
  2. is a "module" package

When importing foo, both rspack and webpack will

  1. bundle content of foo/index.js into the main asset file
  2. and also create an asset file xxxx.js whose content is same as foo/index.js

When minimizing the xxxx.js file, depending on the value of package "type"

package type of foo minimize rspack webpack
"module" ON ❌[1] βœ…
"commonjs" ON ❌[2] ❌[2]
"module" OFF βœ… βœ…
"commonjs" OFF ❌[2] ❌[2]

After dig into it, I just found