Preface
Everyone knows that webpack
will be used when building front-end projects with sass-loader、less-loader、postcss-loader、css-loader、style-loader
, but loader
play in it? This article mainly explains the role and realization of css-loader
and style-loader
, and deepens the understanding loader
css-loader
css-loader
will @import
and url()
, just like js
parses import/require()
, it will generate an array by default to store the processed style strings and export them.
If there are three style files: a.module.scss
, b.module.scss
, c.module.scss
, the dependency between them is as follows:
// a.module.scss
@import './b.module.scss';
.container {
width: 200px;
height: 200px;
background-color: antiquewhite;
}
// b.module.scss
@import url('./c.module.scss');
.text {
font-size: 16px;
color: #da2227;
font-weight: bold;
}
// c.module.scss
.name {
font-size: 16px;;
color: #da7777;
font-weight: bold;
}
Introduce them in the index.jsx
// index.jsx
import React from 'react';
import styles from './a.module.scss';
const Index = () => {
return <div className={styles.container}>
<span className={styles.text}><span className={styles.name}>xxx,</span>hello world!!!</span>
</div>
}
export default Index;
webpack.config.js
build script
// webpack.config.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
index: './src/index.jsx'
},
output: {
filename: 'js/[name].js',
path: path.resolve(__dirname, './dist'),
library: 'MyComponent',
libraryTarget: 'umd',
},
resolve: {
extensions: ['.js', '.jsx', '.tsx'],
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: false, // 禁止css modules
}
},
'sass-loader'
]
},
{
test: /\.(jpg|jpeg|png|gif)$/,
use: ['url-loader']
}
]
},
plugins: [
new webpack.ProgressPlugin(),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['dist']
}),
],
}
.babelrc
configuration
// .babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-class-properties"
]
}
In package.json
configuring the build command "build:dev": "webpack --mode none"
. In order to facilitate the analysis of the code after construction, set mode
to none
here.
Three types of mode
:
development | DefinePlugin set the value of 0618523dcc94aa in process.env.NODE_ENV development . Enable valid names for modules and chunks, that is, replace the module id with the module name. |
---|---|
production | DefinePlugin set the value of 0618523dcc9506 in process.env.NODE_ENV production . enabled certainty for the module and chunk confusing name , FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin and TerserPlugin . |
none | Do not use any default optimization options |
Perform yarn build:dev
build, analyze the generated files
(. 1) a.module.scss
used @import
introduced b.module.scss
, is processed into same module array ___CSS_LOADER_EXPORT___
and export
(2) b.module.scss
uses @import url()
introduce c.module.scss
, but c.module.scss
is processed separately into another module's array ___CSS_LOADER_EXPORT___
and exported
(3) a.module.scss
and b.module.scss
are processed and put into a module array, and c.module.scss
is processed separately and put into another module's array, but b.module.scss
and c.module.scss
are introduced by the relationship. How does this relate to dependencies after construction?
a.module.scss
and b.module.scss
be processed into module id
as 12
array c.module.scss
be processed into module id
as 15
array module id
of 12
module into which a module id
to 15
style array, and append it to the module id
is 12
, and finally __WEBPACK_DEFAULT_EXPORT__
. The css-loader
at this step ends .
In addition,css-loader
also provides other functions, such ascss modules
. If you want to understand, you can refer to the example to open thecss modules
construction to get a glimpse of its principle. I will not introduce it here.
css-loader
Export method
The imported styles mentioned above are all converted into style strings and placed in the module array. This is the default processing method. In fact, there are two other types.
The configuration item exportType
allows the export style to be 'array'
, 'string'
or 'css-style-sheet'
to construct the style (that is, CSSStyleSheet
), the default value: 'array'
CSSStyleSheet
interface represents a CSS style sheet, and allows to check and edit the list of rules in the style sheet. It inherits properties and methods from the parent type StyleSheet
A CSS
style sheet contains a set of CSSRule
objects representing rules. Each CSS
rule can be operated by the objects associated with it. These rules are contained in CSSRuleList
and can be obtained through the cssRules
(en-US) attribute of the style sheet.
For example, CSSStyleRule
object might contain this style:
h1, h2 {
font-size: 16pt;
}
style-loader
style-loader
role is to CSS
inserted DOM
, the process is css-loader
array module derived, then the style by style
inserted tag or other forms DOM
in.
Configuration item injectType
can be configured to insert styles
DOM
, mainly include:
styleTag
: By using a plurality of<style></style>
automaticallystyles
insertedDOM
in. This method is the default behaviorsingletonStyleTag
: Automatically insertstyles
intoDOM
by using a<style></style>
autoStyleTag
: Same asstyleTag
, but when the codeIE6-9
, please opensingletonStyleTag
modelazyStyleTag
: Use multiple<style></style>
to insertstyles
DOM
when needed. Recommendedlazy style
follow use.lazy.css
as a suffix naming conventions,style-loader
basic usage is.css
as the file suffix (other files too, such as:.lazy.less
and.less
). When usinglazyStyleTag
,style-loader
inserts thestyles
. When you need to usestyles
, you can usestyle.use()
/style.unuse()
makestyle
available.lazySingletonStyleTag
: By using a<style></style>
to automaticallystyles
inserted intoDOM
, as described above provide an inert supportlazyAutoStyleTag
: Same aslazyStyleTag
, but when the codeIE6-9
, please openlazySingletonStyleTag
modelinkTag
: Use multiple<link rel="stylesheet" href="path/to/file.css">
to insert styles into the DOM. Thisloader
will be used at run timeJavaScript
dynamically inserted<link href="path/to/file.css" rel="stylesheet">
. To static into<link href="path/to/file.css" rel="stylesheet">
, please use MiniCssExtractPlugin .
We use the styleTag
insertion method for analysis:
All the styles mentioned above are added to id
as 12
, the following first obtains the module array of the module id
as 12
, and then generates the style
label and inserts its style into DOM
_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()
above figure update
method returned by the module in the figure below. This method calls many other methods to insert the style into DOM
style
refer to:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。