salesforce / lwc-webpack-plugin

Plugin to use LWC within Webpack
https://lwc.dev
BSD 3-Clause "New" or "Revised" License
2 stars 4 forks source link

@import CSS stylesheets from node_modules aren't compiled #36

Open cvharris opened 11 months ago

cvharris commented 11 months ago

It seems that this plugin fails to import and compile CSS stylesheets imported within a component CSS itself like so:

@import 'file/from/node_modules.css';

This results in webpack erroring out with a syntax error since it doesn't know how to interpret the CSS file. If we follow Webpack's instructions to add a loader to handle this specific .css, the build error goes away but a browser error appears instead:

Uncaught TypeError: Failed to resolve module specifier "file/from/node_modules.css". Relative references must start with either "/", "./", or "../".

In Rollup, this just works whenever we use the @rollup/plugin-node-resolve plugin before the LWC plugin. Without that plugin the same issue occurs in Rollup.

It seems there should be 1 of 2 possible fixes:

  1. This webpack plugin needs to see CSS @import to files in node_modules and resolve it the same way it resolves CSS modules from node_modules, like @import 'lwc-namespace/css-module';
  2. The webpack config be updated to help this plugin know how to import that file on its own at build time. It does not seem to like having a separate loader try to handle that file for it.
cvharris commented 11 months ago

Here's a StackBlitz with a minimal reproducible setup, showing the working Rollup config and the broken Webpack config: https://stackblitz.com/edit/salesforce-lwc-bsr9jh?file=webpack.config.js

cvharris commented 10 months ago

We did discover a workaround for this issue, though I wonder if this is expected configuration or if it's still an issue for this plugin:

 module: {
    rules: [
      {
        test: /node_modules\/@salesforce-ux\/.+?\.css$/i,
        use: ['style-loader', 'css-loader']
      }
    ]
  }

The above is running style-loader and css-loader only on the imports from specific packages that are imported like so:

@import '@salesforce-ux/sds-common/common.css';

Note: this is different from how LWC handles @imports of LWC CSS modules:

@import wes/styles;

The above line works fine with this plugin, even when the LWC CSS module is installed in node_modules. So the issue seems that LWC only resolves LWC CSS modules from node_modules but skips over any @imports of other css files from node_modules

cvharris commented 9 months ago

Nevermind, the above issue was enabling our build to work, but it prevented LWC from actually rendering the stylesheets on the page. This is still an open issue

cvharris commented 9 months ago

Here's what did it:

  modules: [
        {
          npm: '@sfdc-www/digital-i18n',
        },
        {
          dir: 'node_modules', // <-- 0_0
        },
        {
          npm: '@sfdc-www/wes-lwc-components',
        },
        {
          npm: '@sfdc-www/idx-auth-ui',
        },
        {
          dir: 'src/elements',
        },

The magic is that dir: 'node_modules'. It basically tells the module resolver to handle @import from node_modules to look for those files, and somehow LWC just handles the path url.

But this feels dirty. This is wrong, right? Or is this intended? Are there downsides to allowing LWC to try to resolve modules from any NPM package?

nolanlawson commented 9 months ago

That's really strange @cvharris. I imagine this is some subtle interplay between LWC's module resolver and how Webpack's style loader works. But if it works, it works!