rails icon indicating copy to clipboard operation
rails copied to clipboard

Adding `type: "module"` to actiontext caused an error

Open tomprats opened this issue 2 years ago • 7 comments

In webpack it says

Imports in ESM are resolved more strictly. Relative requests must include a filename and file extension.

By adding type: "module" to actiontext, but not importing with an extension here, importing actiontext generates an error... I think.

Steps to reproduce

In my app/javascript/packs/application.js, importing import "@rails/actiontext" generates an error message when running bin/webpack or bin/webpack-dev-server

It errors with just actiontext, as well an combination of the following:

import "core-js/stable";
import "regenerator-runtime/runtime";
import "@rails/activestorage";
import "@rails/actiontext";
import "@rails/ujs";

Rails.start();

Using actiontext (7.0.0) with webpacker (6.0.0-rc.6). I tried to create a test repo but could not get rails webpacker:install or rails new --webpacker (I think maybe it's gone in favor of the new stuff) to run.

Expected behavior

It should import without an error message

Actual behavior

It generates the following error

ERROR in ./node_modules/@rails/actiontext/app/javascript/actiontext/index.js 1:0-54 Module not found: Error: Can't resolve './attachment_upload' in '/Users/tomify/Desktop/development/visible-voices/node_modules/@rails/actiontext/app/javascript/actiontext' Did you mean 'attachment_upload.js'? BREAKING CHANGE: The request './attachment_upload' failed to resolve only because it was resolved as fully specified (probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '.mjs' file, or a '.js' file where the package.json contains '"type": "module"'). The extension in the request is mandatory for it to be fully specified. Add the extension to the request. resolve './attachment_upload' in '/Users/tomify/Desktop/development/visible-voices/node_modules/@rails/actiontext/app/javascript/actiontext' using description file: /Users/tomify/Desktop/development/visible-voices/node_modules/@rails/actiontext/package.json (relative path: ./app/javascript/actiontext) Field 'browser' doesn't contain a valid alias configuration using description file: /Users/tomify/Desktop/development/visible-voices/node_modules/@rails/actiontext/package.json (relative path: ./app/javascript/actiontext/attachment_upload) Field 'browser' doesn't contain a valid alias configuration /Users/tomify/Desktop/development/visible-voices/node_modules/@rails/actiontext/app/javascript/actiontext/attachment_upload doesn't exist

webpack 5.64.4 compiled with 1 error and 1 warning in 23809 ms

System configuration

Rails version: 7.0.0 Ruby version: 2.7.1

Here is my package.json with potentially relevant libraries. I tested different combinations as well as removing some of them, but the error persists.

{
  "name": "app",
  "browserslist": ["defaults"],
  "dependencies": {
    "@babel/core": "^7.16.0",
    "@babel/plugin-proposal-export-default-from": "^7.16.0",
    "@babel/preset-react": "^7.16.0",
    "@rails/actiontext": "^7.0.0",
    "@rails/activestorage": "^7.0.0",
    "@rails/ujs": "7.0.0",
    "@rails/webpacker": "6.0.0-rc.6",
    "core-js": "^3.18.2",
    "css-loader": "^6.3.0",
    "css-minimizer-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^2.3.0",
    "prop-types": "^15.7.2",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.0.2",
    "regenerator-runtime": "^0.13.9",
    "resolve-url-loader": "^4.0.0",
    "trix": "^1.2.0",
    "webpack": "^5.64.4",
    "webpack-cli": "^4.8.0"
  },
  "devDependencies": {
    "@babel/eslint-parser": "^7.16.0",
    "@babel/eslint-plugin": "7.14.5",
    "@webpack-cli/serve": "^1.5.2",
    "webpack-dev-server": "^4.6.0"
  },
  "private": true,
  "scripts": {
    "dev": "./bin/webpack-dev-server"
  },
  "version": "0.0.0"
}

tomprats avatar Dec 22 '21 18:12 tomprats

Simple workaround for now: copy the contents of https://github.com/rails/rails/blob/7-0-stable/actiontext/app/javascript/actiontext/index.js to your application.js file:

// import "@rails/actiontext";
import { AttachmentUpload } from "@rails/actiontext/app/javascript/actiontext/attachment_upload"

addEventListener("trix-attachment-add", event => {
  const { attachment, target } = event

  if (attachment.file) {
    const upload = new AttachmentUpload(attachment, target)
    upload.start()
  }
})

anamba avatar Dec 28 '21 05:12 anamba

I also see this issue in rails 7.0.2 and @rails/actiontext 7.0.2.

abepark01 avatar Jan 30 '22 01:01 abepark01

With the retirement of Webpacker there won't be any updates to webpacker. I think you might have more luck with its successor: https://github.com/shakacode/shakapacker

p8 avatar Feb 01 '22 18:02 p8

This doesn't affect only webpacker, but the webpack integration via jsbundling-rails, too.

Steps to reproduce:

rails new action-text-webpack-test --javascript webpack
cd action-text-webpack-test 
rails action_text:install

yarn build fails now:

yarn run v1.22.17
$ webpack --config webpack.config.js
assets by status 272 KiB [cached] 1 asset
orphan modules 553 KiB [orphan] 19 modules
runtime modules 670 bytes 3 modules
cacheable modules 554 KiB
  ./app/javascript/application.js + 10 modules 535 KiB [built] [code generated]
  ./node_modules/@rails/actioncable/src/index.js + 9 modules 19 KiB [built] [code generated]

ERROR in ./node_modules/@rails/actiontext/app/javascript/actiontext/index.js 1:0-54
Module not found: Error: Can't resolve './attachment_upload' in '/Users/head/code/action-text-webpack-test/node_modules/@rails/actiontext/app/javascript/actiontext'
Did you mean 'attachment_upload.js'?
BREAKING CHANGE: The request './attachment_upload' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
resolve './attachment_upload' in '/Users/head/code/action-text-webpack-test/node_modules/@rails/actiontext/app/javascript/actiontext'
  using description file: /Users/head/code/action-text-webpack-test/node_modules/@rails/actiontext/package.json (relative path: ./app/javascript/actiontext)
    Field 'browser' doesn't contain a valid alias configuration
    using description file: /Users/head/code/action-text-webpack-test/node_modules/@rails/actiontext/package.json (relative path: ./app/javascript/actiontext/attachment_upload)
      Field 'browser' doesn't contain a valid alias configuration
      /Users/head/code/action-text-webpack-test/node_modules/@rails/actiontext/app/javascript/actiontext/attachment_upload doesn't exist
 @ ./app/javascript/application.js 5:0-26

webpack 5.68.0 compiled with 1 error in 1660 ms
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Rails version: 7.0.1

mrhead avatar Feb 07 '22 16:02 mrhead

I confirm that with latest rails version + jsbundling with webpack, the workaround proposed by @anamba works. I'll keep an eye on this thread for a full resolution 😀

estebanz01 avatar Mar 14 '22 15:03 estebanz01

Looks like this issue is still present when upgrading to shakapacker!

  • Rails 7.0.2.3
  • @rails/actiontext 7.0.2-2
  • shakapacker 6.2.0

OtherCroissant avatar Mar 22 '22 10:03 OtherCroissant

This issue has been automatically marked as stale because it has not been commented on for at least three months. The resources of the Rails team are limited, and so we are asking for your help. If you can still reproduce this error on the 7-0-stable branch or on main, please reply with all of the information you have about it in order to keep the issue open. Thank you for all your contributions.

rails-bot[bot] avatar Jun 20 '22 10:06 rails-bot[bot]

Hello everyone,

I had the same issue 😢 . In my case there were two things to solve:

  1. The first was about the relative path, webpack was looking for '/.attachment_upload' file into my './app/javascript/' folder. As you case see it didn't have much sense because the actiontext library was installed inside the './node_modules' folder.

To solve this, I added the 'node_modules' folder to the resolve modules list in my webpack.config.js file:

module.exports = {
  // ...
  resolve: {
    modules: ['node_modules'] // Added my ./node_modules folder to be taken into account
  },
  // ...
}

  1. The second one was a misunderstanding between actiontext package and webpack about to try with a strict EcmaScript Module.

Due to the own actiontext configuration, it should work as a "strict EcmaScript Module", i.e. it must include the file extension in its internal imports. But it is not doing it for importing the ./attachment_upload file 😢. (At least in the version 7.0.3-1 that I used)

So to fix this, (in my case using Rails 7 and webpack 5), I had to add these settings in my webpack.config.js file:

module.exports = {
  // ...
  resolve: {
    enforceExtension: false // allows webpack to use imports with extension-less
  },
  module: {
    rules: [
      {
        test: /\.m?js$/,
        resolve: {
          fullySpecified: false // allows webpack to ignore some package rules as the Strict EcmaScript Module mode.
        }
      }
    ],
  },
  // ...
}

I hope that this work for you or at least guide you to find your own solution 😊


My complete webpack.config.js file looks like this:

const path    = require('path')
const webpack = require('webpack')

module.exports = {
  mode: 'production',
  devtool: 'source-map',
  // ...
  resolve: {
    modules: ['node_modules'],
    enforceExtension: false // allows webpack to use imports with extension-less
  },
  // ...
  module: {
    rules: [
      {
        test: /\.m?js$/,
        resolve: {
          fullySpecified: false // allows webpack to ignore some package rules as the Strict EcmaScript Module mode.
        }
      }
    ],
  },
  entry: {
    application: './app/javascript/application.js'
  },
  output: {
    filename: '[name].js',
    sourceMapFilename: '[file].map',
    path: path.resolve(__dirname, 'app/assets/builds'),
  },
  plugins: [
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
    })
  ]
}

jefraroce avatar Aug 19 '22 20:08 jefraroce