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

Native CSS support #14893

Open
sokra opened this issue Dec 2, 2021 · 15 comments
Open

Native CSS support #14893

sokra opened this issue Dec 2, 2021 · 15 comments

Comments

@sokra
Copy link
Member

sokra commented Dec 2, 2021

Current State: opt-in via experiments.css: true

Explainer (not everything is implemented yet):

  • experiments.css: true enables the native css support in webpack
  • This will be enabled by default in webpack 6
  • There will be multiple modes depending on how you reference CSS
    • A: import "./style.css": Attaches the stylesheet to the document as side effect of importing. @import and url() are resolved.
    • B: import stylesheet from "./style.css" asset { type: "css" }: Exports the unattached stylesheet as default export. You can adopt it according to the spec. @import is not allowed (yet), but url() will be resolved.
    • C: import { main } from "./style.module.css": Like A, but renames all css classes, keyframes and css variables and exports the new names. Global selectors are only allowed with explicit :global selector prefix. @import and url() are resolved.
    • D: new URL("./style.css", import.meta.url): Gives an URL to a stylesheet including all styles. @import and url() are resolved.
    • E: import { main } from "./style.module.css": Like C, but for the node.js target. It generates a JSON module with the exports from the CSS.
  • A and C will bundle all CSS of a chunk into a single CSS file (per chunk)
  • splitChunks will allow to move CSS around
  • output.cssFilename and output.cssChunkFilename allows to configure the filename template for css files. By default it copies filename resp. chunkFilename with extension changed to .css
  • HMR will update CSS when you edit it.
  • There is external CSS that will lead to @import "..." in the output css files
  • There are external assets that will lead to a external url.
  • class names are based on module ids, so you need to make sure that SSR and Client module ids match
    • E1: Compute module ids in a deterministic way -> DeterministicModuleIdsPlugin
    • E2: Store module ids in a file and load them on the other side -> SyncModuleIdsPlugin
  • In addition to the default bindings, you can use type: "css/..." in rules to apply loader results as css. e. g. for Sass support.
  • This will replace mini-css-extract-plugin and css-loader
  • It will be more performant, by using a css tokenizer instead of postcss
  • There is a css minimizer in production mode.

Implemented:

  • A
  • @import url("...");
  • @import "...";
  • url()
  • chunking
  • on demand loading
  • HMR
  • splitChunks
  • output.cssFilename
  • external type css-import
  • external type asset
  • :export blocks
  • C (partially)
    • classes
    • ids
    • keyframes + animation
    • css variables + var()
  • correct css order in output file
  • warnings for ordering issues
  • E
  • E1
  • E2
  • image-set()
  • @import url("...") layer(test);
  • @import url("...") supports(...);
  • @import url("...") media query;
  • move all external imports to top
  • do not ignore #import and make them external
  • inherit layer, supports(...) and media from parent module
  • supports style resolution in package.json and test it + test support loader usage
  • Implement CSS Module fetchpriority
  • prefetch/preload for CSS

Not implemented/tested, but Planned (ordered by priority):

  • Native CSS support #14893 - allow link be before/after script
  • external import with media/supports
  • image()
  • src()
  • fix bug with publicPath for assets modules inside CSS files
  • :import blocks
  • C (partially)
    • composes: xxx
    • composes: xxx from "..."
    • composes: xxx from global
    • var(xxx from "...")
    • var(xxx from global)
  • contenthashing for CSS files
  • wasm css tokenizer + rewrite to be align with CSS spec + improve logic in callback (more perfomance?) + better error reporting for @import
  • css minimizer
  • D
  • B
  • implement /* webpackIgnore: true */ for url()/image-set()
  • move tests from css-loader to our tests
  • default type: css enables CSS modules support (i.e. for CSS without CSS modules you need set type: "css/global"), which might be a bit confusing for developers, because some developer just want to use pure CSS and parsing CSS modules can affect on perf, I think we should do:
    • type: "css/auto" - enable/disable CSS modules based on path and default type for CSS?
    • type: "css" - no CSS modules and don't try to parse CSS modules things
    • type: "css/module-local" - CSS modules with local mode
    • type: "css/module-global" CSS modules with global mode
  • import sheet from './styles.css' assert { type: 'css' };
  • normalize media/supports/layer to lowercase?
  • pathinfo for @import
  • unstable ?hash generation in --webpack-main when you have multiple same modules
  • url() in css leaves a asset JS Module in js chunk
  • prefeth/preload only for CSS import() generates prefetch/preload runtime for JS
  • url("font.svg#svgFontName") created invalid filename
  • option to do only extract without runtime (for initial and for demard, maybe two options for better compatibility with mini-css-extract-plugin)
@webpack-bot
Copy link
Contributor

This issue had no activity for at least three months.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@alexander-akait
Copy link
Member

bump

@webpack-bot
Copy link
Contributor

Issue was closed because of inactivity.

If you think this is still a valid issue, please file a new issue with additional information.

@alexander-akait
Copy link
Member

/cc @TheLarkInn We have this, so I just will add more things from css-loader/etc so we can see our progress

@alexander-akait
Copy link
Member

Broken URL - #16969 (comment)

@hardfist
Copy link
Contributor

@alexander-akait I'm wondering how experiments.css working with the current css-loader ecosystem,for example https://github.com/seek-oss/css-modules-typescript-loader which consume the result of css-loader, but since experiments.css handle css after loader there're no chances for other loader to get css-module intermediate result, will experiments.css expose some hooks for this scenarios?

@alexander-akait
Copy link
Member

@alexander-akait I'm wondering how experiments.css working with the current css-loader ecosystem,for example https://github.com/seek-oss/css-modules-typescript-loader which consume the result of css-loader, but since experiments.css handle css after loader there're no chances for other loader to get css-module intermediate result, will experiments.css expose some hooks for this scenarios?

It doesn't work, css-loader and etc output a warning and do nothing. Anyway you can set type: ""javascript/auto" and css-loader will work as before.

css-modules-typescript-loader should be rewritten, it should be a plugin which takes CSS dependecies and modify generated code, it is no hard to implement, we can't adopt it and make compatibility, because css-modules-typescript-loader uses generated JS by css-loader, I don't know why it was implemented in such way, because it should be just an option for css-loader (just a custom function that postprocess exports).

@alexander-akait
Copy link
Member

The main idea of the new CSS pipeline - avoid generate JS and CSS multiple times, like we have right now

@hardfist
Copy link
Contributor

i do agree this should be implemented as plugin and no need to be compatible,how this plugin should be implemented becomes a problem,should this plugin consume css dep directly and do the same codegen logic as internal css codegen or should it just consume the intermediate result of intetnal css module processing

@alexander-akait
Copy link
Member

@hardfist

i do agree this should be implemented as plugin and no need to be compatible,how this plugin should be implemented becomes a problem,should this plugin consume css dep directly and do the same codegen logic as internal css codegen or should it just consume the intermediate result of intetnal css module processing

Yeah, we need to think about it, maybe we can introduce extra hooks to simplify this process, let's keep this here, We wanted to finish normal CSS support firslty and then I will think about it and put in our test cases a simplified example

@hardfist
Copy link
Contributor

hardfist commented Jun 26, 2023

I'm not sure whether all the options in css-loader and mini-css-extract-plugin will be supported in experiments.css, and we're migrating some applications from css-loader & mini-css-extract-plugin to experiments.css and missing some functionalities, so maybe I can track these in this issue or file separate issue?

if these functionalities are accepted we're willing to implement it for webpack

@fregante
Copy link

fregante commented Sep 3, 2023

from #17700

It's unclear how to get the old extract + css-loader setup: generate CSS files and do nothing else.

Currently it appears that experiments.css: true generates the CSS files but also tries to load them, causing this error in my environment (web extension)

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
    at loadCssChunkData (refined-github.js:28644:21)

Which wasn't the case with the following configuration:

module: {
	rules: [
		{
			test: /\.css$/,
			use: [
				MiniCssExtractPlugin.loader,
				'css-loader',
			],
		},
	]
},
plugins: [
	new MiniCssExtractPlugin(),
],

@jeromehan
Copy link

jeromehan commented Sep 11, 2023

getComputedStyle

@fregante This might help you #16147 (comment)

@fregante
Copy link

No, webpack should not run any JavaScript if I ask it to generate a CSS file, so that isn't useful for this scenario.

@Sushil642
Copy link

Dear @sokra ,

I am Sushil SIngh. I'm writing to express my interest in contributing to the ongoing enhancement of Webpack's CSS capabilities, specifically Issue #14893 . I have reviewed the provided information and believe that I possess the necessary skills to make meaningful contributions to the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Priority - High
Development

No branches or pull requests

7 participants