"Webpack"--style loading

Source: Internet
Author: User

Loading CSS requires Css-loader and Style-loader Css-loader to process @import and URLs into regular ES6 import, and if @import points to an external resource, Css-loader skips, Only the internal resources are processed. After Css-loader processing, the Style-loader will inject the output CSS into the packaged file. CSS is the inline mode by default and implements the HMR interface. But inline is not very suitable for production environments (all output on the page). You also need to use Extracttextplugin to generate a separate CSS file, but take a step-by-step. One, Style Pack 1. Install Css-loader,style-loader
NPM Install Css-loader Style-loader--save-dev
2. Modify Webpack.config.js Add a primary child node
  module:{       rules:[{       test:/\.css$/, use       : [' Style-loader ', ' Css-loader '],     }]    },
The regular of Test matches the. css file. The order of execution in use is right-to-left. The execution of loader is continuous, just like a pipe, first to Css-loader and then to Style-loader. Loaders: [' Style-loader ', ' css-loader '] can be understood as: Styleloader (Cssloader (input)). 3. Add Style App/mian.css
{  background: cornsilk;}

And then introduce it in the index.js.

Import './main.css ';

Run NPM start again, open in http://localhost:8080/

This time the page has a background color, and found that the style has been written to the header, when you change the color, the interface will not refresh the update, this is the effect of the previous section HMR.

Styles are also updated through the Webpackhotupdate method.

Second, load less

And look at how to load less, install Less-loader first

NPM Install less Less-loader--save-dev

Then modify the configuration file:

   module:{       rules:[{          /\.less$/, use  : [' Style-loader ', ' css-loader ', '  Less-loader'],             }]    },

Then create a less file. Less.less

{  -webkit-box-shadow: @style @c;   box-shadow:         @style @c;}  {  . Box-shadow (@style, rgba (0, 0, 0, @alpha));}  {  color: saturate (@base, 5);   Border-color: lighten (@base, 30%);  }  {  background: cornsilk;}

Modify Index.js

Import  './less.less '; import component from './component '; var ele=document.createelement ("div"); ele.innerhtml= "This is a box"; ele.classname= " box";d ocument.body.appendChild (ele); let democomponent=component (); Document.body.appendChild (democomponent);

Get results:

Can see the compilation success, it should be noted that the use of less when the import can only be less files, and then import MAIN.CSS will be an error. This section makes a simple demonstration of less, and the other style preprocessor, in the same vein, continues to be based on CSS.

Iii. Understanding CSS Scopes and CSS modules

In general, the scope of the CSS is global, we often add more than one style file in the master page, the following style file will overwrite the previous style files, often to our debugging trouble. CSS modules introduces the local scope through import. This avoids namespace collisions. Webpack Css-loader is to support CSS modules, how to understand, first look at a few examples. Let's start with the configuration (turn off HMR first):

    module:{       rules:[{        test:/\.css$/, use        : [' Style-loader ', {        ' Css-loader ',          options: {         true,//Let Css-loader support CSS Modules.         },        },],

Then define a new style (MAIN.CSS):

body {  background:cornsilk;}. Redbutton {  background:red;color:yellow;}

Add a style to component and introduce MAIN.CSS first.

import styles from './main.css ' ; default function () {  var element = document.createelement (' h1 ');      Element.classname=styles.  Redbutton;      = ' Hello webpack ';   return element;}

This time we see that the interface has changed.

Looking at the generated style on the right, our style name has changed. Recalling that the entire process is equivalent to each of the Main.css class name into a module, in JS can be obtained as a module. But you might think, for Mao, I can't assign a value to an element directly, why import it? This is a good question, let's add another style

Class with the same name for different style files

Other.css

. Redbutton {  Background:rebeccapurple;color:snow;}

It also has a. Redbutton class (But the effect is purple), and then creates a DIV element in index.js and adds a Redbutton style to it.

Import './main.css ';   './other.css ' ;'. /component '; var ele=document.createelement ("div"); ele.innerhtml= "This is a other button";  Ele.classname=Styles.redbutton; Document.body.appendChild (ele); let democomponent=component ();d Ocument.body.appendChild (democomponent );

Look at the effect again

The above figure illustrates the two problem, one is that we introduced 2 style files in the index.js, the output of two style on the index page, this is a bit uncomfortable, but we will solve later. The other is that although there are redbutton in both style files, the two remain separate. This avoids the mutual interference of namespaces. If you were to assign a value directly at this time,

Element.classname= "Redbutton";

This is not available for the style. The style of the element directly is global by default.

Global style

If you want a style to be global. Can be wrapped by: global.

Other.css

: Global {  background:rebeccapurple; color:snow;   Border: 1px solid red;}

Main.css

{  background: Red; color:yellow;}

This time Redbutton the two styles will be merged. It needs to be obtained directly from the style name.

Element.classname= "Redbutton";

Combining styles

We then modified the OTHER.CSS to create a Shadowbutton style, which redbutton the class internally through the composes combination.

{  background:rebeccapurple; color:snow;   Border: 1px solid red;} . Shadowbutton {    composes:Redbutton;     box-shadow: 0 0 15px black;}

Modify Index.js:

var ele=document.createelement ("div"); ele.innerhtml= "This was an Shadowbutton button";  Console.log (styles); Ele.classname=styles.  Shadowbutton;d ocument.body.appendChild (ele);

See what the effect is:

The log prints out the styles object, which contains two class names. You can see that Shadowbutton is a combination of two class names. The div's class corresponds to the following.

Four, output style file CSS embedded in the page is not what we want, we want to be able to separate, the public part can be separated. Extracttextplugin can synthesize multiple CSS into one file, but it does not support HMR (directly commenting out hotonly:true). Used in the production environment is very good
NPM Install Extract-text-webpack-plugin--save-dev

Install Extracttextplugin This plug-in first, and then configure it in Webpack.config.js:

Const Extracttextplugin = require (' Extract-text-webpack-plugin '); Const Extracttxtplugin=Newextracttextplugin ({ filename: ' [name]. [Contenthash:8].css ',}); Const Commonconfig ={entry: {app:PATHS.app,}, Output: {path:PATHS.build, filename:' [Name].js ',}, module:{rules:[{test:/\.css$/, use:extractTxtplugin.extract({use:' Css-loader ', fallback:' Style-loader ',          }) }]}, plugins: [NewHtmlwebpackplugin ({title:' Webpack demo ', }), Extracttxtplugin ],}

It was a bit confusing to see this configuration at first. First look at filename, which indicates that the last output file follows this format ' [name]. [contenthash:8].css ', name default is the corresponding folder name (here is the app), Contenthash will return the hash value of the specific content, and: 8 means take the first 8 bits. Of course you can also write in other formats, such as direct naming:

New Extracttextplugin (' Style.css ')

And extracttextplugin.extract itself is a loader. Fallback: ' Style-loader ' means but there is no CSS to be extracted (external CSS) when you use the Style-loader to handle. Notice now that our index.js are as follows:

Import './main.css '; import Styles from'./other.css '; Import component from'./component ';varEle=document.createelement ("div"); ele.innerhtml= "This was an box"; Ele.classname=Styles.shadowbutton;document.body.appendchild (ele); let DemoComponent=component ();d ocument.body.appendChild (democomponent);//HMR Interfaceif(module.hot) {module.hot.accept ('./component ', () ={Const Nextcomponent=component ();        Document.body.replaceChild (nextcomponent,democomponent); DemoComponent=nextcomponent; })}
View Code

Two CSS files were introduced.

This time we execute NPM Run build

Then look at the folder to get a style file. (If you don't want to see the log directly NPM build)

But we used the CSS Modules in the third part, and found that the OTHER.CSS style was not packaged in. So, we have to revise the webpack.config.js:

   module:{       rules:[{           test:/\.css$/,           use:extractTxtplugin.extract ({            use:[{              ' Css-loader ',            options: {            true,        },        }],             ' Style-loader ',          }}     ]},

Build again.

Found two styles packaged as a file. As soon as the content changes, the name of the style changes. More configuration can be https://www.npmjs.com/package/extract-text-webpack-plugin

Summary: This article is a bit more content, from the basic style packaging, to less, and then know the CSS Modules. The final package outputs the entire file. It can be said that the novice or a little complex, the tool brings convenience, naturally also bring the cost of learning. Many options and many configurations finally, we need to find a suitable for our own configuration, and understand the mechanism of each module to face different needs of different collocation. This section original code: Http://files.cnblogs.com/files/stoneniqiu/webpack-ch4.zip

Reference:

Https://www.npmjs.com/package/css-loader#local-scope

https://survivejs.com/webpack/styling/loading/

https://survivejs.com/webpack/styling/separating-css/series: "Webpack"--Getting Started and parsing "webpack"--automatic refresh and resolution "Webpack"--Module Hot swap

"Webpack"--style loading

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.