Skip to content

Commit

Permalink
Import application JS as a module (#178)
Browse files Browse the repository at this point in the history
Bun.js generates JS bundles in the ESM format and they need be imported with
the `type="module"` attribute. Otherwise the module varibles end up in the
global scope. See hotwired/turbo#1077

This commit updates the install generator to add the type="module" attribute
to the default `javascript_include_tag`.

`defer` is no longer needed, as JS modules are deferred by default.

Ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_standard_scripts

This PR also updates the default config to ensure that all bundlers are
configured to output ESM bundles.

- bun only supports ESM at the moment https://bun.sh/docs/bundler#format
- esbuild is configured to output ESM with the --format=esm flag https://esbuild.github.io/api/#format-esm
- webpacker is configured to output ESM bundles with `output.chunkFormat` https://webpack.js.org/configuration/output/#outputchunkformat
- rollup is configured to output ESM bundles with `output.format` https://rollupjs.org/configuration-options/#output-format
  • Loading branch information
afcapel committed Jan 5, 2024
1 parent 95a5472 commit 880a1bd
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/install/esbuild/install.rb
Expand Up @@ -2,7 +2,7 @@
run "yarn add esbuild"

say "Add build script"
build_script = "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets"
build_script = "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets"

case `npx -v`.to_f
when 7.1...8.0
Expand Down
4 changes: 2 additions & 2 deletions lib/install/install.rb
Expand Up @@ -14,10 +14,10 @@
if (app_layout_path = Rails.root.join("app/views/layouts/application.html.erb")).exist?
say "Add JavaScript include tag in application layout"
insert_into_file app_layout_path.to_s,
%(\n <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>), before: /\s*<\/head>/
%(\n <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %>), before: /\s*<\/head>/
else
say "Default application.html.erb is missing!", :red
say %( Add <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> within the <head> tag in your custom layout.)
say %( Add <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %> within the <head> tag in your custom layout.)
end

unless (app_js_entrypoint_path = Rails.root.join("app/javascript/application.js")).exist?
Expand Down
2 changes: 1 addition & 1 deletion lib/install/rollup/rollup.config.js
Expand Up @@ -4,7 +4,7 @@ export default {
input: "app/javascript/application.js",
output: {
file: "app/assets/builds/application.js",
format: "iife",
format: "esm",
inlineDynamicImports: true,
sourcemap: true
},
Expand Down
1 change: 1 addition & 0 deletions lib/install/webpack/webpack.config.js
Expand Up @@ -10,6 +10,7 @@ module.exports = {
output: {
filename: "[name].js",
sourceMapFilename: "[file].map",
chunkFormat: "module",
path: path.resolve(__dirname, "app/assets/builds"),
},
plugins: [
Expand Down

0 comments on commit 880a1bd

Please sign in to comment.