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

Beta build not working in Storybook with Webpack 5 #43

Closed
MichaelAllenWarner opened this issue Dec 31, 2021 · 6 comments · Fixed by #47
Closed

Beta build not working in Storybook with Webpack 5 #43

MichaelAllenWarner opened this issue Dec 31, 2021 · 6 comments · Fixed by #47
Labels
bug Something isn't working

Comments

@MichaelAllenWarner
Copy link

(Following up on our conversation here.)

I've created a repo demonstrating the problem.

The master branch uses the alpha build of drupal-twig-extensions and works fine (clone repo, do npm install, and then npm run storybook).

The dte-beta branch uses the beta-3 build of drupal-twig-extensions and doesn't work. Here is the ESM-ified twing-environment.js file for that branch, with some comments explaining the situation.

I'm not sure exactly what Storybook and Webpack are doing under the hood here, but so far the only solution I've found is sticking with the alpha build.

@MichaelAllenWarner
Copy link
Author

I feel like I'm close with syntax like this:

const {
  TwingEnvironment,
  TwingLoaderRelativeFilesystem,
} = require('twing');

const twing = new TwingEnvironment(
  new TwingLoaderRelativeFilesystem(),
  { autoescape: false }
);

module.exports = import('drupal-twig-extensions/twing').then(
  ({ addDrupalExtensions }) => {
    addDrupalExtensions(twing);
    return twing;
  }
);

(I can successfully console.log both addDrupalExtensions and twing inside the .then()).

But twing-loader is throwing an error that must mean that the Promise stuff at the bottom isn't working as I'd hoped:

ModuleBuildError: Module build failed (from ./node_modules/twing-loader/dist/index.js):
TypeError: environment.getLoader is not a function

Tried some variations, including with an async IIFE, but no dice yet.

@MichaelAllenWarner
Copy link
Author

Yes, problem with above attempt is that it sets module.exports not to twing itself but rather to a Promise that resolves to twing. Here is another attempt that correctly exports the twing object and then mutates it asynchronously in the .then():

const {
  TwingEnvironment,
  TwingLoaderRelativeFilesystem,
} = require('twing');

const twing = new TwingEnvironment(
  new TwingLoaderRelativeFilesystem(),
  { autoescape: false },
);

import('drupal-twig-extensions/twing').then(
  ({ addDrupalExtensions }) => {
    addDrupalExtensions(twing);
  }
);

module.exports = twing;

But apparently the mutation occurs too late, because I get this error: Unable to add filter "${filter.getName()}" as extensions have already been initialized.


To summarize the whole problem:

  • Unless I change the file-extension to .mjs, I can't use ES import in this file:
ModuleBuildError: Module build failed (from ./node_modules/twing-loader/dist/index.js):
/[...]/dte-storybook/.storybook/twing-environment.js:14
import {
^^^^^^

SyntaxError: Cannot use import statement outside a module
  • Changing the file-extension to .mjs doesn't work because twing-loader uses require:
ModuleBuildError: Module build failed (from ./node_modules/twing-loader/dist/index.js):
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /[...]/dte-storybook/.storybook/twing-environment.mjs
  • As a result, I have to use the dynamic import() to bring in drupal-twig-extensions, but the asynchronous nature of import() is preventing me from actually applying drupal-twig-extensions to the exported twing object before twing-loader processes it.

@JohnAlbin JohnAlbin added the bug Something isn't working label Jan 1, 2022
@JohnAlbin JohnAlbin changed the title Beta build not working in Storybook Beta build not working in Storybook with Webpack 5 Jan 1, 2022
@JohnAlbin
Copy link
Owner

Yep. I've confirmed everything you said in your previous post.

So, twing-loader is NOT compatible with Webpack 5. It says it requires Webpack 4 on the homepage. Which means Webpack 5 is probably using a backwards-compatiblity layer to get twing-loader to work using old-school webpack-4 APIs. And that explains why twing-loader can't handle ES Modules properly.

The proper fix for this issue is to upgrade twing-loader to be Webpack 5 compatible. There is a PR mentioning Webpack 5 warnings, but the PR doesn't actually upgrade the APIs.

And using that PR still results in this error:

ModuleBuildError: Module build failed (from ../twing-loader/dist/index.js):
Error [ERR_REQUIRE_ESM]: require() of ES Module node_modules/drupal-twig-extensions/lib/twing.js from .storybook/twing-environment.js not supported.

I'm using Storybook with webpack 4 successfully (I set up that project in March 2021), but I want to use webpack 5 now that Storybook supports that.

I think a quick work-around would be for drupal-twig-extensions to re-add Babel-compiled CommonJS files.

@MichaelAllenWarner
Copy link
Author

@JohnAlbin

Thanks for the response.

FYI (in case you missed it), here is how I make twing-loader compatible with Webpack 5.

@JohnAlbin
Copy link
Owner

JohnAlbin commented Jan 4, 2022

@MichaelAllenWarner Please try 1.0.0-beta.4 and use CommonJS in the file that imports it. Thanks!

@MichaelAllenWarner
Copy link
Author

@JohnAlbin That's great—thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants