web-infra-dev / rspack

The fast Rust-based web bundler with webpack-compatible API 🦀️
https://rspack.dev
MIT License
9.72k stars 559 forks source link

[Bug]: When using jsx in vue2 and replacing babel-loader with builtin:swc-loader to compile .js files, an error will be reported #7575

Closed asasugar closed 2 months ago

asasugar commented 2 months ago

System Info

System: OS: macOS 14.5 CPU: (11) arm64 Apple M3 Pro Memory: 1.07 GB / 36.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.17.0 - ~/.nvm/versions/node/v16.17.0/bin/node Yarn: 1.22.22 - /opt/homebrew/bin/yarn npm: 8.15.0 - ~/.nvm/versions/node/v16.17.0/bin/npm pnpm: 8.15.6 - ~/.nvm/versions/node/v16.17.0/bin/pnpm Browsers: Chrome: 127.0.6533.119 Safari: 17.5 npmPackages: @rspack/cli: ^0.7.5 => 0.7.5 @rspack/core: ^0.7.5 => 0.7.5

Details

vue@2.6.11 vue-loader@15.11.0

module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        include: [SPA_PATH, path.resolve(__dirname, '../node_modules/element-ui')],
        use: {
          loader: 'vue-loader',
          options: {
            compilerOptions: { preserveWhitespace: false },
            experimentalInlineMatchResource: true,
          }
        },
      },
      // {
      //   test: [/\.js$/],
      //   include: SPA_PATH,
      //   use: [
      //     'babel-loader?cacheDirectory'
      //   ]
      // },
      // TODO: 目前如果js用builtin:swc-loader,那么编译.vue文件的js部分会报错
      {
        test: [/\.jsx$/],
        exclude: /(node_modules)/,
        use: {
          loader: 'builtin:swc-loader',  // builtin:swc-loader swc-loader都可以
          options: {
            parseMap: true,
            sourceMap: true,
            jsc: {
              parser: {
                decorators: true,
                dynamicImport: true,
                syntax: "ecmascript",
                jsx: true,
              },
              target: "es5",
              experimental: {
                plugins: [
                  'swc-plugin-vue-jsx', {},
                  '@swc/plugin-remove-console', // need to use specific version to be compatible with rspack's internal swc version
                  {
                    exclude: ['error'],
                  },
                ]
              },
              externalHelpers: true,
              preserveAllComments: false,
              loose: true,
              transform: {
                legacyDecorator: true,
                decoratorMetadata: true,
                react: {
                  runtime: 'automatic',
                  throwIfNamespace: true,
                  useBuiltins: false,
                },
              },
            },
          },
        },
        type: 'javascript/auto',
      },
      {
        test: /\.js$/,
        exclude: file => (
          /node_modules/.test(file) &&
          !/\.vue\.js/.test(file)
        ),
        use: {
          loader: 'builtin:swc-loader',
          // options: {
          //   sourceMap: true,
          //   jsc: {
          //     parser: {
          //       syntax: "ecmascript",
          //       jsx: true,
          //     },
          //     // experimental: {
          //     //   plugins: ['@vue/babel-plugin-jsx']
          //     // },
          //     transform: {
          //       react: {
          //         // 默认是React.createElement,这样会报错ReferenceError: h is not defined,两种解决方法:
          //         // 1.core/index.js中引入h方法挂载到window但是会影响全局组件的注册,如:MainBars找不到;
          //         // 2.DefinePlugin先定义一个变量'Vue_CreacteElement': 'h',然后配置 `transform.react.pragma = 'Vue_CreacteElement'`
          //         pragma: 'h',
          //       },
          //     },
          //   },
          // },
        },
        type: 'javascript/auto',
      },
      {
        test: /\.less$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'less-loader',
        ],
        type: 'javascript/auto',
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader',
        ],
        type: 'javascript/auto',
      },
      // Static Files - SVG Font
      {
        test: /webfonts.*\.svg$/,
        type: 'asset/inline',
      },
      {
        test: /\.svga$/i,
        type: "asset/inline",
      },
      // Static Files - Images
      {
        test: [
          /\.bmp$/,
          /\.gif$/,
          /\.jpe?g$/,
          /\.png$/,
          /\.eot$/,
          /\.ttf/,
          /\.woff/,
          /\.svg/,
          /\.woff2/
        ],
        type: 'asset/resource',
      }
    ]
  }

}

Reproduce link

如上所述

Reproduce Steps

如上所述

chenjiahan commented 2 months ago

SWC only supports compiling React JSX, so you cannot use swc-loader to compile Vue JSX syntax.

To compile Vue JSX, babel-loader is still required, refer to: https://rspack.dev/guide/tech/vue#vue-3-jsx

chenjiahan commented 2 months ago

It is not possible to use transform.react. pragma to transform Vue JSX, their outputs are completely different.