ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.4k stars 775 forks source link

Can't load ESM modules in config #3003

Open Alxandr opened 2 years ago

Alxandr commented 2 years ago

Stencil version:

 @stencil/core@2.6.0

I'm submitting a:

[x] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:

When trying to import a ESM module in the config file (in my example, globby), the build fails with:

[ ERROR ]  Error [ERR_REQUIRE_ESM]: require() of ES Module
           C:\Git\PolicyStaging.WebComponents\node_modules\globby\index.js from
           C:\Git\PolicyStaging.WebComponents\build\stencil\icu\gen\dts.ts not supported. Instead change the require of
           index.js in C:\Git\PolicyStaging.WebComponents\build\stencil\icu\gen\dts.ts to a dynamic import() which is
           available in all CommonJS modules.

Expected behavior:

The build should work as expected.

Steps to reproduce:

Create a stencil.config.ts, import and use globby@12 from it.

splitinfinities commented 2 years ago

Can you please link me to a reproduction repo? I want to understand how you're importing globby. Also, could you try this out and let me know if it resolves like you intend. Reads to me like a dependency of Globby doesn't use ESM.

import { Config } from '@stencil/core';
import {nodeResolve} from '@rollup/plugin-node-resolve';

export const config: Config = {
  // ...
  rollupPlugins: {
    before: [nodeResolve({browser: true})],
  }
};
Alxandr commented 2 years ago

The repo is unfortunately private, however all I did was import { globbySync } from 'globby';. The issue is that you're not allowed to require node ESM modules. Node will throw. You have to use import (either the statement or the dynamic import expression).

Alxandr commented 2 years ago

Also. I'm not trying to import globby in my app. I'm trying to import globby in my config. So nodeResolve in your example has no use as it's in the configuration file. A better example:

import { Config } from '@stencil/core';
import { globbySync } from 'globby';

const files = globbySync(.......);
export const config: Config = {
  // use files somehow
};
rwaskiewicz commented 2 years ago

Hey @Alxandr,

The reason you're unable to use globby is a limitation of Stencil at the moment. By default, stencil.config.ts is treated as a commonjs module, which is what I suspect is causing the issue here. I'm going to label this issue to get it ingested for us to take a closer look and see what we can do here

Alxandr commented 2 years ago

I know that is the reason :) - but I probably did a bad job of explaining it. As far as I know there are only 2 ways of fixing this (and this issue will likely become more prevalent as more and more packages are converted to ESM btw) - one is to import the config as an esm module (this requires changing the transpilation of the config) - or a simpler temporary solution is to allow config to be async. This would enable calling import('globby') in the config - which you can do from an common-js module.

n1kk commented 2 years ago

I have a similar issue with importing a rollup plugin. Is there any way to change how stensils' config is compiled? Otherwise, it seems like ESM packages and plugins are unusable.

Trying to import this

import mdx from '@mdx-js/rollup'; 

This is the error I'm getting

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:
    _PROJECT_/node_modules/.pnpm/@mdx-js+rollup@2.0.0-rc.1/node_modules/@mdx-js/rollup/index.js
    require() of ES modules is not supported. require() of
    _PROJECT_/node_modules/.pnpm/@mdx-js+rollup@2.0.0-rc.1/node_modules/@mdx-js/rollup/index.js
    from _PROJECT_/stencil.config.ts is an ES module file as it is a .js
    file whose nearest parent package.json contains "type": "module" which defines all .js files in that package
    scope as ES modules. Instead rename index.js to end in .cjs, change the requiring code to use import(), or
    remove "type": "module" from
    _PROJECT_/node_modules/.pnpm/@mdx-js+rollup@2.0.0-rc.1/node_modules/@mdx-js/rollup/package.json.

Doesn't seem like I have control over any end (stencil config/rollup plugin source).

benmb1984 commented 1 year ago

Is there any update on this? I also got stuck beceause of this issue. Or is there a work around that I can apply on my side?

azan-n commented 1 year ago

Same issue here. Would like to import my ESM tailwind conf to import into the tailwind plugin.

oscargm commented 5 months ago

Reproducing the same when trying to use stylex with stencil

npm run build

> stencil-stylex@0.0.1 build
> stencil build

[41:16.9]  @stencil/core
[41:17.1]  v4.9.1 🍬

[ ERROR ]  Error [ERR_REQUIRE_ESM]: require() of ES Module
           /home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stylexjs/rollup-plugin/lib/index.js
           from /home/users/garciamo/roche/repositories/garciamo/stencil-stylex/stencil.config.ts not supported.
           Instead change the require of index.js in
           /home/users/garciamo/roche/repositories/garciamo/stencil-stylex/stencil.config.ts to a dynamic import()
           which is available in all CommonJS modules. at Object.<anonymous>
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/stencil.config.ts:7:41) at
           require.extensions..ts
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stencil/core/compiler/stencil.js:259617:24)
           at nodeRequire
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stencil/core/compiler/stencil.js:259624:26)
           at evaluateConfigFile
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stencil/core/compiler/stencil.js:260896:25)
           at loadConfigFile
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stencil/core/compiler/stencil.js:260867:38)
           at Object.loadConfig
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stencil/core/compiler/stencil.js:260810:40)
           at Object.run
           (/home/users/garciamo/roche/repositories/garciamo/stencil-stylex/node_modules/@stencil/core/cli/index.cjs:2443:46)

Isn't there a way to treat stencil.config.ts as an ESM module? (or any plans to support?) Is there any advance done or something we can do?

rwaskiewicz commented 5 months ago

Isn't there a way to treat stencil.config.ts as an ESM module?

Not at this time, although there are plans to support it. I don't have a definitive timeline, but this work is on our roadmap

elclanrs commented 4 days ago

This seems like a major blocking issue. Does it really mean that no ESM package can be used the Stencil config? @oscargm did you find a workaround?