You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Special chars in CSS Class Names not Stripped from Exports (Causes Error) #45
Thanks for taking over this project - I have a project template for React projects that depended on its predecessor and its nice to see someone picked it up.
Anyways, I've updated all deps (npx npm-check-updates -u && npm install) and after a bit of a configuration update The only error I'm getting that's preventing my compilation from completing successfully is:
ERROR in ./src/components/NodeKitCore/styles.scss (./node_modules/@teamsupercell/typings-for-css-modules-loader/src/index.js??ruleSet[1].rules[5].use[1]!./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[5].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[5].use[3]!./src/components/NodeKitCore/styles.scss) 10:13
Module parse failed: Unexpected token (10:13)
File was processed with these loaders:
* ./node_modules/@teamsupercell/typings-for-css-modules-loader/src/index.js
* ./node_modules/css-loader/dist/cjs.js
* ./node_modules/sass-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
|export const standard = "_1FcZ2DoWKoMNzwvFsPE8n5";|export const titleCapture = "_17mdMcJ5k7O5pYNkH6zUEi";>export const +fullHeight = "_9aH9R-E-_bPyqa-v7dM67";|export const +inverseColors = "_3Ur4Mt3ewSPWrwd_rncbkO";|export const +flex = "_2AQUPgQwN28XGDEtM17H7A";
@ ./src/components/NodeKitCore/styles.scss 2:12-306 9:17-24 13:15-29
@ ./src/components/NodeKitCore/index.ts 12:15-39
@ ./src/containers/App/App.tsx 18:22-61
@ ./src/containers/App/index.ts 14:12-28
@ ./src/app.tsx 15:14-41
I'd bother posting the source files, but I can just tell you that in a scss file somewhere along the way I have:
&.\+full-height {
height: 100%;
}
And according to the error, what's happening is that @teamsupercell/typings-for-css-modules-loader is attempting to create the export: export const +fullHeight = "_9a...";.
This is causing an error of course.
I'm leveraging the exportsLocalConvention: "camelCaseOnly" and namedExports: true options in css-loader.
Any idea on how I can get around this error? Could you ensure that named exports will generate only codeSafeNames ( String.replace() any special chars not allowed in variable names) in a subsequent release?
I might very well compile a pull request myself - but if this is a simple enough fix for you I'd imagine being the one to have been maintaining the plug-in you know exactly where to implement said check.
If I'm off about who's to blame for the issue please let me know . Thanks!
I want to add in that the reason I'm assuming the issue is with your loader is because this is "no longer a stand-in replacement for css-loader", and in the previous maintainer's package this issue did not happen, exports did not contain any special chars in the name and using the special char in the css class names worked just fine.
Anyways, just so you can see my webpack configuration (webpack.config.babel.js) I'll post it in this follow up comment:
// INCLUDESimport*aspathfrom'path';importHtmlWebPackPluginfrom"html-webpack-plugin";importMiniCssExtractPluginfrom"mini-css-extract-plugin";// DEFINESmodule.exports={entry:
{// We specify the entry so we can use a custom entry point// Otherwise index.js is expected (anywhere in folder stucture)app: "./src/app.tsx"},output:
{//filename: "bundle.js",path: path.resolve(__dirname,'dist'),},// Enable sourcemaps for debugging webpack's output:devtool: "source-map",resolve:
{// Add '.ts' and '.tsx' as resolvable extensions.extensions: ['.ts','.tsx','.js','.jsx',".css",".scss",'.json']},module:
{rules:
[// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader':{test: /.tsx?$/,use:
[{loader: "awesome-typescript-loader"}]},// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader':{enforce: "pre",test: /.js$/,use:
[{loader: "source-map-loader"}]},// ES6/7 JavaScript will be handled by babel-loader{test: /.js$/,//exclude: /node_modules/,use:
[{loader: "babel-loader"}]},{// HTML Templatetest: /.html$/,use: [{loader: "html-loader",options: {minimize: false}}]},{// Image Optimizationtest: /.(gif|png|jpe?g|svg)$/i,use:
[{loader: "url-loader",options:
{exclude: /.(svg)$/i,name: "./images/[name]_[hash:7].[ext]",limit: 10000}},{loader: 'img-loader'}]},{// SCSS Compilationtest: /\.(scss|css)$/,//include: [// path.resolve(__dirname, "src/scss")//],use:
[{loader: "style-loader"},{// We'll use a drop-in replacement for css-loader which supports importing// SCSS within a typescript file//loader: "css-loader"//loader: "typings-for-css-modules-loader", <-- no longer maintained as of 2017??loader: "@teamsupercell/typings-for-css-modules-loader",options:
{// Options are now passed directly to "css-loader"}},{loader: "css-loader",options: {modules: {compileType: "module",namedExport: true,exportLocalsConvention: "camelCaseOnly",//mode: "local",//auto: true,//exportGlobals: true,//exportOnlyLocals: false}}},{loader: "sass-loader",options:
{sassOptions: {includePaths: ["node_modules"]}}}]}]},plugins:
[newHtmlWebPackPlugin({favicon: "src/assets/favicon.ico",template: "src/index.html",filename: "./index.html"}),newMiniCssExtractPlugin({filename: "[name].css",chunkFilename: "[id].css"})],// When importing a module whose path matches one of the following, just assume a corresponding global// variable exists and use that instead. This is important as it allows us to avoid bundling all of our// dependencies, which subsequently allows browsers to cache those libraries between builds://externals://{// "react": "React",// "react-dom": "ReactDOM"//}};
So it seems that I've been slightly mistaken on what was going on. There have been several issues, and I'm thinking that there's more than just this loader to consider. Mind you I've updated from:
declarenamespaceStylesScssNamespace{exportinterfaceIStylesScss{consoleFont: string;contentBlock: string;contentBlockInner: string;footer: string;standard: string;titleCapture: string;}}declareconstStylesScssModule: StylesScssNamespace.IStylesScss&{/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */locals: StylesScssNamespace.IStylesScss;};export=StylesScssModule;
Misconceptions & Initial Fix
I made my initial fix based on the idea that the output I was seeing in the error (shared in my initial post) was an excerpt from style.d.ts - mistakenly failing to recognize that it was not displaying exported types (exported to styles.d.ts), but exported variables (exported to app.js, the output from Webpack as defined in my configuration).
As a result I had presumed I needed to build a loader to chain off of typings-for-css-modules that would strip the + character from the exported types. However, I was only correcting css-loader's exported symbols.
NOTEThe use of + characters in my custom naming convention for CSS I refuse to drop or modify because it makes rapid development so slick when I use kwaeri user experience and friends.
I found that several new errors appeared, and it led me to discovering that:
Was pulling in an external CSS library, which css-loader was tripping over. I could not, for the life of me, get Webpack to overlook this file. I tried exclude rules, changing the test to only look for /\.scss$/, and ultimately settled on removing the link from the entry and adding it in manually to the output index.html.
I thought I had succeeded, because my exported types (from styles.d.ts) and the named exports (within app.js) were properly reflected - and my project now built. However, when rendering the application in the browser I found that everywhere I had used styles.namedClass in my presentation components, the injected values were undefined and the application was not reflecting styles properly.
Updated Changes
// INCLUDESimport*aspathfrom'path';importHtmlWebPackPluginfrom"html-webpack-plugin";//import MiniCssExtractPlugin from "mini-css-extract-plugin";importExtractCssChunksfrom'extract-css-chunks-webpack-plugin'// DEFINESconstdevMode=process.env.NODE_ENV!=='production';module.exports={entry: {// We specify entry for a custom entry point, or index.js expected (anywhere):app: "./src/app.tsx"},output: {//filename: "bundle.js", or just a path to keep entry name:path: path.resolve(__dirname,'dist'),},devtool: "source-map",// Enable sourcemaps for debugging webpack's output:resolve: {// Add '.ts' and '.tsx' as resolvable extensions:extensions: ['.ts','.tsx','.js','.jsx',/*".css",*/".scss",'.json']},module: {rules: [{// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'enforce: "pre",test: /\.js$/,//use: [ { loader: "source-map-loader" } ]use: "source-map-loader"},{// ES6/7 JavaScript will be handled by babel-loadertest: /\.js$/,//use: [ { loader: "babel-loader" } ]use: "babel-loader"},{// HTML Templatetest: /\.html$/,use: [{loader: "html-loader",options: {minimize: false}}]},{// Image Optimizationtest: /\.(gif|png|jpe?g|svg)$/i,// Trying to figure out where to exclude this file so it's not processed due to being present via <link> in index.htmlexclude: [path.resolve('./src/assets/css/kwaeri-ux-md.css')],use: [{loader: "url-loader",options: {exclude: /.(svg)$/i,name: "./images/[name]_[hash:7].[ext]",limit: 10000}},'img-loader']},{// SCSS Compilationtest: /\.(sa|sc)ss$/,exclude: [path.resolve('./src/assets/css/kwaeri-ux-md.css')],use: [{// Have HMR in development and styles extracted in a file for production builds://loader: devMode ? 'style-loader' : MiniCssExtractPlugin.loader,loader: ExtractCssChunks.loader,options: {hmr: devMode// process.env.NODE_ENV === 'development'}},{// Remove missed special chars from class names (such as '+') - still working this out:loader: path.resolve('./loaders/fix-typings-exports-loader.js'),options: {replacerText: ""}},// Generate typings for Typescript support:"@teamsupercell/typings-for-css-modules-loader",{loader: "css-loader",options: {importLoaders: 1,modules: {//compileType: "module", // <-- can be 'module' or 'icss' - module by default//mode: "local", // <-- 'local', 'global', or 'pure' - local by default//namedExport: true, // <-- false by default//auto: true, // <-- requires that files match *.module.* by default? Seems not when left unspecified. Can be bool/regex/func//exportGlobals: true, // <-- false by defaultexportLocalsConvention: "camelCaseOnly",// or camelCase (to remove original class name from locals) https://github.com/webpack-contrib/css-loader#exportlocalsconvention//exportOnlyLocals: true, // <-- false by default//sourceMap: true, // <-- almost always true}}},{loader: "postcss-loader",options: {postcssOptions: {plugins: ()=>[postcssPresetEnv({stage: 0})]}},},{loader: "sass-loader",options:
{sassOptions: {includePaths: ["node_modules"]}}}]},{// All files with a '.ts' or '.tsx' extension will be handled by ts-loader or 'awesome-typescript-loader':test: /\.tsx?$/,exclude: /node_modules/,use: "ts-loader"// Or awesome-typescript-loader to transpile with babel instead of tsc},]},optimization: {splitChunks: {cacheGroups : {styles: {name: 'styles',test: /\.css$/,chunks: 'all',enforce: true,}}}},plugins: [newHtmlWebPackPlugin({favicon: "src/assets/favicon.ico",template: "src/index.html",filename: "./index.html"}),newExtractCssChunks({filename: devMode ? '[name].css' : '[name].[hash].css',chunkFilename: devMode ? '[id].css' : '[id].[hash].css',ignoreOrder: false})/*, new MiniCssExtractPlugin ( { filename: "[name].css", chunkFilename: "[id].css" } )*/],// When importing a module whose path matches one of the following, just assume a corresponding global// variable exists and use that instead. This is important as it allows us to avoid bundling all of our// dependencies, which subsequently allows browsers to cache those libraries between builds://externals://{// "react": "React",// "react-dom": "ReactDOM"//}};
Originally in my endeavor to update npm dependencies the exported types retained their original form:
export const xxx: string;
However, after several attempts at configuration changes to get my project to build and render properly my style's typings have taken on the above referenced new form. This is due to css-loader now filing most things under locals - having changed the entire template to the modules that are generated.
As a result I've made use of a different configuration for css-loaders than I did in my previous configuration - as depicted in my new Webpack configuration.
I've replaced MiniCssExtractPlugin with CssExtractChunks
CssExtractChunks allows me to implement HMR, and properly extracts all the CSS to a separate stylesheet (app.css in my case)
Current Issues
Accommodating the locals implementation that css-loader has adopted for its CSS module template has exposed another issue whereby any CSS classes I've defined that use a + character are entirely stripped from typings generated by typings-for-css-modules. This breaks compilation due to Typescript errors being thrown as typings are not generated for said classes which are used within Typescript-based React components:
ERROR in /home/rik/workspaces/edison-computers/core-react/src/components/NodeKitCore/NodeKitCore.tsx
./src/components/NodeKitCore/NodeKitCore.tsx
[tsl] ERROR in /home/rik/workspaces/edison-computers/core-react/src/components/NodeKitCore/NodeKitCore.tsx(55,32)
TS2339: Property 'nodekitAppContainerInner' does not exist on type'IStylesScss & { locals: IStylesScss; }'.
@ ./src/components/NodeKitCore/index.ts 17:20-44
@ ./src/containers/App/App.tsx 37:22-61
@ ./src/containers/App/index.ts 15:12-28
@ ./src/app.tsx 37:14-41
ERROR in /home/rik/workspaces/edison-computers/core-react/src/components/NodeKitCore/NodeKitCore.tsx
./src/components/NodeKitCore/NodeKitCore.tsx
[tsl] ERROR in /home/rik/workspaces/edison-computers/core-react/src/components/NodeKitCore/NodeKitCore.tsx(59,36)
TS2339: Property 'nodekitAppContainerStage' does not exist on type'IStylesScss & { locals: IStylesScss; }'.
@ ./src/components/NodeKitCore/index.ts 17:20-44
@ ./src/containers/App/App.tsx 37:22-61
@ ./src/containers/App/index.ts 15:12-28
@ ./src/app.tsx 37:14-41
As such I have to keep going back into the styles.d.ts file for the only presentation component that has these classes (the majority of my CSS classes which do have a + symbol are solely in my external UX library - kux), and undo (ctrl+z) the change (a freshly generated typings file missing the two aforementioned classes). After doing so the app will build after handling the next point:
I can't figure out how to get Webpack to ignore the <link> including kux. So I have to keep it removed from the entry index.html file and to keep on manually adding it to the generated index.html
Potential Fix
I need to figure out how to keep that <link> tag from being processed so it doesn't choke compilation.
I'm just working through different exclude rules for different loaders within different sections of my Webpack configuration in hope of figuring out where it's getting pulled in. Excluding in the section with css-loader seems to not work at all, even when my test doesn't even match *.css. If I remove the file altogether I get an error that it's not found (naturally).
The only other option is figure out why the heck css-loader won't just take the pure CSS and bundle it into the output (or prefix the generated CSS). I get the following error when I don't remove the <link> reference from index.html:
ERROR in Error: Child compilation failed:
Module parse failed: Unexpected token (25:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|$mdc-theme-on-background: #fdfdfd;|*/
> .mdc-touch-target-wrapper {
| display: inline; }
|:
SyntaxError: Unexpected token (25:0)
ModuleParseError: Module parse failed: Unexpected token (25:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|$mdc-theme-on-background: #fdfdfd;|*/
> .mdc-touch-target-wrapper {
| display: inline; }
|
It makes no sense as its valid CSS, and I don't have CSS files being tested in my Webpack configuration. This has been my biggest delay thus far.
Similarly I have to figure out how to prevent entire CSS class names generated by the SCSS compiler/loader which have a + character in it from being entirely ignored by typings-for-css-modules so they can have typings generated for them. I'm not sure if its css-loader or typings-for-css-modules that's to blame for this, but I'm suspicious of the latter due to:
While typings-for-css-modules is failing to generate the type definitions for the respective classes entirely (as shown in the error messages above), the generated hash styles are not missing from Webpack's ouptut (they're in both the CSS modules exported by css-loader - and in the CSS file generated by CssExtractChunks), and the class name hashes are properly injected into the React output and properly reflect in the rendering of the application once it compiles.
This might have to do with the ordering of my custom loader, of the typings-for-css-modules loader, both aforementioned points - or something else entirely.
Activity
kirvedx commentedon Dec 9, 2020
I want to add in that the reason I'm assuming the issue is with your loader is because this is "no longer a stand-in replacement for css-loader", and in the previous maintainer's package this issue did not happen, exports did not contain any special chars in the name and using the special char in the css class names worked just fine.
Anyways, just so you can see my webpack configuration (webpack.config.babel.js) I'll post it in this follow up comment:
kirvedx commentedon Dec 10, 2020
A work around I've implemented involved creating a directory named
loadersin the root of my project source, with this file in it:fix-typings-exports-loader.js:
Then I added another loader to my webpack configuration:
webpack.config.babel.js:
This did the trick.
kirvedx commentedon Dec 12, 2020
Latest Update
So it seems that I've been slightly mistaken on what was going on. There have been several issues, and I'm thinking that there's more than just this loader to consider. Mind you I've updated from:
To:
So Webpack has been updated to
> 5.0, Typescript to>4.0, React to>17- and all of the loaders have been respectively updated as well.Issues
This has resulted in a number of issues, naturally.
v5vsv4works is a bit different.Misconceptions & Initial Fix
I made my initial fix based on the idea that the output I was seeing in the error (shared in my initial post) was an excerpt from
style.d.ts- mistakenly failing to recognize that it was not displaying exported types (exported tostyles.d.ts), but exported variables (exported toapp.js, the output from Webpack as defined in my configuration).As a result I had presumed I needed to build a loader to chain off of typings-for-css-modules that would strip the
+character from the exported types. However, I was only correcting css-loader's exported symbols.NOTE The use of
+characters in my custom naming convention for CSS I refuse to drop or modify because it makes rapid development so slick when I use kwaeri user experience and friends.I found that several new errors appeared, and it led me to discovering that:
Was pulling in an external CSS library, which css-loader was tripping over. I could not, for the life of me, get Webpack to overlook this file. I tried exclude rules, changing the test to only look for
/\.scss$/, and ultimately settled on removing the link from the entry and adding it in manually to the outputindex.html.I thought I had succeeded, because my exported types (from
styles.d.ts) and the named exports (withinapp.js) were properly reflected - and my project now built. However, when rendering the application in the browser I found that everywhere I had usedstyles.namedClassin my presentation components, the injected values wereundefinedand the application was not reflecting styles properly.Updated Changes
Originally in my endeavor to update npm dependencies the exported types retained their original form:
export const xxx: string;However, after several attempts at configuration changes to get my project to build and render properly my style's typings have taken on the above referenced new form. This is due to css-loader now filing most things under
locals- having changed the entire template to the modules that are generated.As a result I've made use of a different configuration for css-loaders than I did in my previous configuration - as depicted in my new Webpack configuration.
I've replaced MiniCssExtractPlugin with CssExtractChunks
CssExtractChunks allows me to implement HMR, and properly extracts all the CSS to a separate stylesheet (
app.cssin my case)Current Issues
Accommodating the locals implementation that css-loader has adopted for its CSS module template has exposed another issue whereby any CSS classes I've defined that use a
+character are entirely stripped from typings generated by typings-for-css-modules. This breaks compilation due to Typescript errors being thrown as typings are not generated for said classes which are used within Typescript-based React components:As such I have to keep going back into the
styles.d.tsfile for the only presentation component that has these classes (the majority of my CSS classes which do have a+symbol are solely in my external UX library - kux), and undo (ctrl+z) the change (a freshly generated typings file missing the two aforementioned classes). After doing so the app will build after handling the next point:I can't figure out how to get Webpack to ignore the
<link>including kux. So I have to keep it removed from the entryindex.htmlfile and to keep on manually adding it to the generatedindex.htmlPotential Fix
I need to figure out how to keep that
<link>tag from being processed so it doesn't choke compilation.I'm just working through different
excluderules for different loaders within different sections of my Webpack configuration in hope of figuring out where it's getting pulled in. Excluding in the section with css-loader seems to not work at all, even when mytestdoesn't even match*.css. If I remove the file altogether I get an error that it's not found (naturally).The only other option is figure out why the heck css-loader won't just take the pure CSS and bundle it into the output (or prefix the generated CSS). I get the following error when I don't remove the
<link>reference fromindex.html:It makes no sense as its valid CSS, and I don't have CSS files being tested in my Webpack configuration. This has been my biggest delay thus far.
Similarly I have to figure out how to prevent entire CSS class names generated by the SCSS compiler/loader which have a
+character in it from being entirely ignored by typings-for-css-modules so they can have typings generated for them. I'm not sure if its css-loader or typings-for-css-modules that's to blame for this, but I'm suspicious of the latter due to:This might have to do with the ordering of my custom loader, of the typings-for-css-modules loader, both aforementioned points - or something else entirely.
That's where I'm at 🤕