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

Cannot emit "use strict" with SWC optimizer & with basic Babel usage #9280

Open
lb- opened this issue Sep 30, 2023 · 1 comment
Open

Cannot emit "use strict" with SWC optimizer & with basic Babel usage #9280

lb- opened this issue Sep 30, 2023 · 1 comment

Comments

@lb-
Copy link

lb- commented Sep 30, 2023

🐛 bug report

I have been unable to get "use strict" to be added to my exported code with the swc compiler, even when adding it manually it will be removed by the production build step.

🎛 Configuration (.babelrc, package.json, cli command)

package.json

{
  "name": "use-strict-example",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "browserslist": "IE 11",
  "scripts": {
    "build": "node build.js"
  },
  "devDependencies": {
    "@parcel/config-default": "2.9.3",
    "@parcel/core": "2.9.3",
    "parcel": "2.9.3"
  }
}

build.js

import { Parcel } from "@parcel/core";

let bundler = new Parcel({
  entries: "./src/index.js",
  defaultConfig: "@parcel/config-default",
  defaultTargetOptions: {
    context: "browser",
    outputFormat: "global",
    sourceMaps: false,
  },
  mode: "production",
});

try {
  let { bundleGraph, buildTime } = await bundler.run();
  let bundles = bundleGraph.getBundles();
  console.log(`✨ Built ${bundles.length} bundles in ${buildTime}ms!`);
} catch (err) {
  console.log(err.diagnostics);
}

Create a single file src/index.js

"use strict";
(() => {
  const foo = "bar";
  foo2 = "bar2";
  console.info("use strict?");
})();

🤔 Expected Behavior

With or without the "use strict"; added at the top of my file, I would expect a way to set this automatically.

dist/index.js

"use strict";
foo2="bar2",console.info("use strict?");

Or better, would be keeping the iffe wrapper to enclose JS variables.

"use strict";!function(){foo2="bar2",console.info("use strict?")}();

😯 Current Behavior

dist/index.js

foo2="bar2",console.info("use strict?");

No matter what I do, I cannot seem to get "use strict" to appear at the top, even adding a .babelrc does not allow this.

Other things I have tried

  • Add .babelrc to change the compile step, using babel-preset-env alongside the babel-plugin-transform-strict-mode plugin. It has no effect.
  • Add a .terserrc with various attempts at declaring ecma 5, nothing seems to make much difference at all.
  • Attempt to add strictMode: true to the terserrc as this is supported by SWC, I just get an error though.

Further to this, now I want the "use strict" to be added automatically.

This required me to add .babelrc with the simple 'default' config, even though Parcel docs say that if you use this default you may not need it. It does produce a different output. See https://parceljs.org/languages/javascript/#default-presets

💁 Manual workaround

My manual work around is to stop using swc at all, once I add the following config/package.json, it works great. See https://parceljs.org/languages/javascript/#minification

  1. Install the terser optimizer npm install --save-dev @parcel/optimizer-terser
  2. Add .parcelrc (below)
{
  "extends": "@parcel/config-default",
  "optimizers": {
    "*.js": [
      "@parcel/optimizer-terser"
    ]
  }
}

This works much better, not only do I get the required "use strict" but my function wrapper is kept in place as expected, not exposing variables to the global namespace.

!function(){"use strict";foo2="bar2",console.info("use strict?")}();
  1. Next, you need to add .babelrc as follows.
{
  "presets": ["@babel/preset-env"]
}

With that change you no longer need to manually include "use strict"; in your JS file and it gets correctly added.

To recap

You need to both use terser optimizer AND add a babelrc with the default config to get an ouput that will work for a 'script' injection.

🔦 Context

My goal is a ecma 5 script only target, something we can inject into older browsers and it just work, irrespective of how it's added, no polluting globals, so we need to transpile AND minify. Parcel and Webpack are the only tools that seem to support this all in one go.

  • So far it's taken a day or so of on and off exploration to get this far, it's very confusing what context & outputFormat impact and what they do not, I thought they had an impact but it seems to do nothing.
  • There appear to be gaps in how SWC has been adopted, some configs seem to change things and some do not (in terserrc), I understand that SWC is faster (it's great!) but I have really struggled to understand that the terser config is used for SWC.
  • Also, SWC config is not used, so anything that's documented in SWC is not going to work.

💻 Code Sample

🌍 Your Environment

Software Version(s)
Parcel 2.9.3
Node 20.7.0
npm/Yarn 10.1.0
Operating System macOS 13.0
"@babel/core" "7.23.0"
"@babel/preset-env" "7.22.20",
"@parcel/optimizer-terser" "2.9.3"

Notes

Thank you, I know bundling is hard, I have tried in the last few days SWC (vanilla), Rollup, Esbuild and Parcel appears to be quite flexible while keeping config to a minimum.

I just wanted to help communicate this issue and maybe there can be future consideration of 'script' as a first class output target or some docs to fill in the gaps for this use case.

@lb- lb- changed the title Cannot emit "use strict" with swc optimizer Cannot emit "use strict" with swc optimizer & with basic babel usage Sep 30, 2023
@lb- lb- changed the title Cannot emit "use strict" with swc optimizer & with basic babel usage Cannot emit "use strict" with SWC optimizer & with basic Babel usage Sep 30, 2023
@github-actions github-actions bot added the Stale Inactive issues label Mar 28, 2024
@lb-
Copy link
Author

lb- commented Mar 29, 2024

I'm not aware of this being fixed, it's still a problem that we have a manual workaround in our code.

@github-actions github-actions bot removed the Stale Inactive issues label Mar 29, 2024
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

No branches or pull requests

1 participant