Import Css File Into Es6 Returns String Instead Of Object
Solution 1:
I think you have mistake in your Webpack
config. You have nested rules
property, instead you should have use
:
{
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
}
Solution 2:
I'm sorry, but I have to revert my last statement. My issue has NOT been resolved by @Akxe's comment.
Now my import statement (import * as test from '...'
) resolves to an object, but it's still not correct.
I have set up a GIT Repo to reproduce the issue. The readme.md
file explains the repro and the issue.
It looks like Webpack is not executing/evaluating the return value of the loader.
Btw. this is not just the case with the css-loader. The result stays the same for raw-loader, sass-loader, style-loader, etc.
My final goal is to lazily load my theme files into a storybook. I try to follow the documentation of the @etchteam/storybook-addon-css-variables-> theme.
Solution 3:
Finally I got my issue solved!
Analysis
The main issue here is the webpack configuration generated by the @angular-devkit/build-angular
package. I was able to analyze it by debugging a fresh angular12 application (you can check it out here).
By setting a break-point at /node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js
, function: generateWebpackConfig(...)
, I could inspect the final webpackConfig
object in the debugger.
The relevant rule looks like this:
The important part here is the rule setting the module type to
asset/source
, instructing webpack not to evaluate the loader's result.
Solution concept 1: inline loader
With the help of alexander-kait and his great hints at this issue, I was able to find an inline-loader syntax that overrides webpack's module declaration:
importTestfrom'test.css.webpack[javascript/auto]!=!!!style-loader?injectType=lazyStyleTag!css-loader!./test.css';
console.log(typeofTest); // output: objectconsole.log(Test); // output: Object { use: () => void, unuse: () => void }Test.use(); // this should usually be called by a theme switcher...
I'm not really sure about the url pattern here, as it seems to be an undocumented feature, but I assume that it's something like <query-pattern>.webpack[<module-type>]!=!<loaders><query>
.
However, since this is an undocumented feature, I was rather reluctant to use it.
Solution concept 2: webpackConfig customization
Since I'm in a storybook context, I decided to customize the webpack configuration according to the storybook documentation.
My solution requires to set up a naming convention (e.g. *.theme.css
).
// .storybook/main.jsmodule.exports = {
webpackFinal: async (config) => {
// exclude *.theme.css from the *.css ruleset
config.module.rules.find(rule =>'.css'.match(rule.test)).exclude = [ /\.(?:theme\.css)$/i ];
// add a rule for *.theme.css
config.module.rules.push({
test: /\.(?:theme\.css)$/i,
use: [
{ loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
'css-loader',
],
});
},
};
With these rules in place, I can now simply do the following:
// preview.jsimportLightThemefrom'./light.theme.css';
importDarkThemefrom'./dark.theme.css';
setupThemeSwitcher(LightTheme, DarkTheme);
Please note that the
setupThemeSwitcher
function is just pseudocode merely there for the example. In reality I'm using the @etchteam/storybook-addon-css-variables-theme addon...
Solution 4:
I had a very similar issue with storybook and this extension, except l’m loading .scss files. I simply adapted solution 2 to suit my .scss case and it works like a charm. I couldn’t make solution 1 to work, but as stated, it sounds hacky whereas solution 2 is cleaner in my opinion. Thanks a lot for sharing this solution, I was struggling for hours.
Post a Comment for "Import Css File Into Es6 Returns String Instead Of Object"