欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

webpack 樣式加載的實(shí)現(xiàn)原理

 更新時(shí)間:2018年06月12日 09:16:05   作者:stoneniqiu  
本篇文章主要介紹了webpack 樣式加載的實(shí)現(xiàn)原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

加載css需要用到css-loader和style-loader css-loader將@import 和 url 處理成正規(guī)的ES6 import ,如果@import指向的是一個(gè)外部資源,css-loader會(huì)跳過(guò),而只會(huì)對(duì)內(nèi)部資源做處理。css-loader處理之后,style-loader會(huì)將輸出的css注入到打包文件中。css默認(rèn)是inline模式,且實(shí)現(xiàn)了HMR接口。但inline不太適用于生產(chǎn)環(huán)境(全部輸出在頁(yè)面上)。還需要用extracttextplugin生成一個(gè)單獨(dú)的css文件,但先一步一步來(lái)。

一,樣式打包

1.安裝css-loader,style-loader

npm install css-loader style-loader --save-dev

2.修改webpack.config.js增加一個(gè)一級(jí)子節(jié)點(diǎn)

module:{
  rules:[{
  test:/\.css$/,
  use: ['style-loader', 'css-loader'],
  }]
 },

test的正則會(huì)匹配.css的文件。use中的執(zhí)行順序是從右到左。loader的執(zhí)行是連續(xù)的,就像管道一樣,先到css-loader再到style-loader。loaders: ['style-loader', 'css-loader'] 可以理解為:styleloader(cssloader(input)) 。

3.添加樣式

app/mian.css

body {
 background: cornsilk;
}

然后在index.js中引入

import './main.css';

再運(yùn)行npm start,在http://localhost:8080/中打開(kāi)

這時(shí)候頁(yè)面出現(xiàn)了背景色,而且發(fā)現(xiàn)樣式寫(xiě)入了header中,這個(gè)時(shí)候你改變顏色,界面也會(huì)無(wú)刷新的更新,這正是上一節(jié)HMR的效果。

樣式也是通過(guò)webpackHotUpdate方法進(jìn)行更新。

二、加載less

再看一下如何加載less,先安裝less-loader

npm install less less-loader --save-dev

再修改配置文件:

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

然后建立一個(gè)less文件。less.less

@base: #f938ab;

.box-shadow(@style, @c) when (iscolor(@c)) {
 -webkit-box-shadow: @style @c;
 box-shadow:   @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
 .box-shadow(@style, rgba(0, 0, 0, @alpha));
}
.box {
 color: saturate(@base, 5%);
 border-color: lighten(@base, 30%);
 div { .box-shadow(0 0 5px, 30%) }
}

body {
 background: cornsilk;
}

修改index.js

import './less.less';
 import component from './component';

var ele=document.createElement("div");
ele.innerHTML="this is an box";
ele.className="box";
document.body.appendChild(ele);

let demoComponent=component();
document.body.appendChild(demoComponent);

得到效果:

可以看見(jiàn)編譯成功,要注意的是,再使用less的時(shí)候import只能是less文件,這個(gè)時(shí)候再import main.css會(huì)報(bào)錯(cuò)。這一節(jié)對(duì)less就做一個(gè)簡(jiǎn)單的演示,其他樣式預(yù)處理器同理,下面的內(nèi)容還是繼續(xù)基于css。

三、理解css作用域和css 模塊

一般來(lái)說(shuō)css的作用域都是全局的,我們常在母版頁(yè)里面添加了多個(gè)樣式文件,后面的樣式文件會(huì)覆蓋前面的樣式文件,常常給我們的調(diào)試帶來(lái)麻煩。而CSS Modules通過(guò)import引入了本地作用域。這樣能夠避免命名空間沖突。webpack的css-loader是支持CSS Modules的,怎么理解呢,先看幾個(gè)例子。我們先在配置中開(kāi)啟(先關(guān)掉HMR):

module:{
  rules:[{
  test:/\.css$/,
  use: ['style-loader', {
  loader: 'css-loader',
   options: {
   modules: true,//讓css-loader支持Css Modules。
  },
  },],

然后定義一個(gè)新的樣式(main.css):

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

給component加一個(gè)樣式,先引入main.css。

import styles from './main.css';
export default function () {
 var element = document.createElement('h1');
  element.className=styles.redButton;
  element.innerHTML = 'Hello webpack';
 return element;
}

這個(gè)時(shí)候我們看到界面已經(jīng)變化了。

再看右邊生成的樣式,我們的樣式名稱已經(jīng)發(fā)生了改變?;仡櫿麄€(gè)過(guò)程相當(dāng)于main.css中的每一個(gè)類名成了一個(gè)模塊,在js中可以像獲取模塊一樣的獲取。但是你可能想,為毛我不能直接給元素賦值,干嘛要import呢。這是個(gè)好問(wèn)題,我們?cè)傩略鲆粋€(gè)樣式

不同樣式文件的同名類

other.css

.redButton {
 background:rebeccapurple;color:snow;
}

它也有一個(gè).redbutton的類(但效果是紫色的),然后在index.js中創(chuàng)建一個(gè)div元素并給它添加redbutton樣式。

import './main.css';
import styles from './other.css';
import component from './component';

var ele=document.createElement("div");
ele.innerHTML="this is an other button";
ele.className=styles.redButton;
document.body.appendChild(ele);

let demoComponent=component();
document.body.appendChild(demoComponent);

再看效果

上面這個(gè)圖說(shuō)明了兩問(wèn)題,一個(gè)是我們?cè)趇ndex.js中引入了2個(gè)樣式文件,在index頁(yè)面就輸出了兩個(gè)style,這讓人有點(diǎn)不爽,但我們后面再解決。另外一個(gè)就是雖然兩個(gè)樣式文件中都有redButton這個(gè)類,但是這兩者還是保持獨(dú)立的。這樣就避免了命名空間的相互干擾。如果你這個(gè)時(shí)候直接賦值

element.className="redButton";

這樣是獲取不到樣式的。直接對(duì)元素的樣式默認(rèn)是全局的。

全局樣式

如果想讓某個(gè)樣式是全局的??梢酝ㄟ^(guò):global來(lái)包住。

other.css

:global(.redButton) {
 background:rebeccapurple;color:snow;
 border: 1px solid red;
}

main.css

:global(.redButton) {
 background: red;color:yellow;
}

這個(gè)時(shí)候redbutton這兩個(gè)樣式就會(huì)合并。需要直接通過(guò)樣式名來(lái)獲取。

element.className="redButton";

組合樣式

我們?cè)傩薷膐ther.css,創(chuàng)建一個(gè)shadowButton 樣式,內(nèi)部通過(guò)composes組合redbutton類。

.redButton {
 background:rebeccapurple;color:snow;
 border: 1px solid red;
}
 
.shadowButton{
 composes:redButton;
 box-shadow: 0 0 15px black;
}

修改index.js:

var ele=document.createElement("div");
ele.innerHTML="this is an shadowButton button";
console.log(styles);
ele.className=styles.shadowButton;
document.body.appendChild(ele);

看一下是什么效果:

日志打印出來(lái)的是styles對(duì)象,它包含了兩個(gè)類名??梢钥匆?jiàn)shadowButton是由兩個(gè)類名組合而成的。div的class和下面的對(duì)應(yīng)。

四、輸出樣式文件

css嵌在頁(yè)面里面不是我們想要的,我們希望能夠分離,公共的部分能夠分開(kāi)。extracttextplugin 可以將多個(gè)css合成一個(gè)文件,但是它不支持HMR(直接注釋掉hotOnly:true)。用在生產(chǎn)環(huán)境挺好的

npm install extract-text-webpack-plugin --save-dev

先安裝extracttextplugin這個(gè)插件,然后再webpack.config.js中進(jìn)行配置:

const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractTxtplugin = new ExtractTextPlugin({
 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: [
 new HtmlWebpackPlugin({
  title: 'Webpack demo',
 }),
 extractTxtplugin
 ],
}

一開(kāi)始看到這個(gè)配置,讓人有點(diǎn)懵。首先看fileName,表示最后輸出的文件按照這個(gè)格式'[name].[contenthash:8].css',name默認(rèn)是對(duì)應(yīng)的文件夾名稱(這里是app),contenthash會(huì)返回特定內(nèi)容的hash值,而:8表示取前8位。當(dāng)然你也可以按照其他的格式寫(xiě),比如直接命名:

new ExtractTextPlugin('style.css')

而ExtractTextPlugin.extract本身是一個(gè)loader。fallback:'style-loader'的意思但有css沒(méi)有被提取(外部的css)的時(shí)候就用style-loader來(lái)處理。注意到現(xiàn)在我們的index.js如下:

import './main.css';
import styles from './other.css';
import component from './component';

var ele=document.createElement("div");
ele.innerHTML="this is an box";
ele.className=styles.shadowButton;
document.body.appendChild(ele);

let demoComponent=component();
document.body.appendChild(demoComponent);

//HMR 接口
if(module.hot){
 module.hot.accept('./component',()=>{
  const nextComponent=component();
  document.body.replaceChild(nextComponent,demoComponent);
  demoComponent=nextComponent;
 })
}

引入了兩個(gè)css文件。

這個(gè)時(shí)候我們執(zhí)行 npm run build

再看文件夾得到一個(gè)樣式文件。(如果不想看到日志可以直接npm build)

但是我們?cè)诘谌糠质褂昧薈SS Modules,發(fā)現(xiàn)other.css的樣式?jīng)]有打包進(jìn)來(lái)。所以,我們的webpack.config.js還要修改:

module:{
  rules:[{
   test:/\.css$/,
   use:extractTxtplugin.extract({
   use:[ {
   loader: 'css-loader',
   options: {
   modules: true,
  },
  }],
   fallback: 'style-loader',
   })
  }]},

再次build。

發(fā)現(xiàn)兩個(gè)樣式打包成了一個(gè)文件。只要內(nèi)容發(fā)生了變化,樣式的名稱就會(huì)變化。更多配置可以移步https://www.npmjs.com/package/extract-text-webpack-plugin

小結(jié):這一篇講的內(nèi)容有點(diǎn)多了,從基本的樣式打包,到less,然后認(rèn)識(shí)CSS Modules。最后打包輸出整個(gè)文件??梢哉f(shuō)對(duì)于新手還是有點(diǎn)復(fù)雜,工具帶來(lái)了便利性,自然也帶來(lái)了學(xué)習(xí)的成本。諸多選擇和諸多配置的最后,我們要找到一個(gè)適合我們自己的配置,并了解各個(gè)模塊的機(jī)制才能面對(duì)不同需求的不同搭配。本節(jié)原碼:http://xz.jb51.net:81/201806/yuanma/webpack-ch4_jb51.rar

參考:

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

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

https://survivejs.com/webpack/styling/separating-css/

系列:

【webpack】-- 入門(mén)與解析

【webpack】-- 自動(dòng)刷新與解析

【webpack】-- 模塊熱替換

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • FF和IE之間7個(gè)JavaScript的差異

    FF和IE之間7個(gè)JavaScript的差異

    盡管 JavaScript 歷史上使用冗長(zhǎng)而令人生厭的代碼塊來(lái)標(biāo)的特定瀏覽器的時(shí)期已經(jīng)結(jié)束了,但是偶爾使用一些簡(jiǎn)單的代碼塊和對(duì)象檢測(cè)來(lái)確保一些代碼在用戶機(jī)器上正常工作依然是必要的。
    2009-05-05
  • js 彈出框只彈一次(二次修改之后的)

    js 彈出框只彈一次(二次修改之后的)

    彈出框只彈一次,看到網(wǎng)上也就寫(xiě)的很多,可以直接使用的沒(méi)有幾個(gè),下面與大家分享個(gè)修改之后的代碼,需要的朋友可以參考下
    2013-11-11
  • javascript中l(wèi)ength屬性的探索

    javascript中l(wèi)ength屬性的探索

    本文中,我將會(huì)通過(guò)類數(shù)組對(duì)象(array like object),探索javascript中的length屬性的一些秘密。
    2011-07-07
  • javascript客戶端生成MD5值的函數(shù)代碼

    javascript客戶端生成MD5值的函數(shù)代碼

    用js實(shí)現(xiàn)的客戶端即可實(shí)現(xiàn)md5值的代碼,一般情況下都是后臺(tái)語(yǔ)言才有的,客戶端也有了,方便有需要的朋友了。
    2011-02-02
  • JS對(duì)select控件option選項(xiàng)的增刪改查示例代碼

    JS對(duì)select控件option選項(xiàng)的增刪改查示例代碼

    Javascript操作select是表單中比較常見(jiàn)的,大家可以在網(wǎng)上搜索到很多的相關(guān)資料,接下來(lái)為大家詳細(xì)介紹下,JS動(dòng)態(tài)操作select中的各種方法,感興趣的朋友可以參考下
    2013-10-10
  • JS顯示日歷和天氣的方法

    JS顯示日歷和天氣的方法

    這篇文章主要介紹了JS顯示日歷和天氣的方法,涉及JavaScript日期與時(shí)間的操作技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2016-03-03
  • require.js中的define函數(shù)詳解

    require.js中的define函數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于require.js中define函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用require.js中的define函數(shù)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • JS清除選擇內(nèi)容的方法

    JS清除選擇內(nèi)容的方法

    這篇文章主要介紹了JS清除選擇內(nèi)容的方法,較為詳細(xì)的分析了js操作文本的技巧,需要的朋友可以參考下
    2015-01-01
  • 原生JavaScript實(shí)現(xiàn)批量獲取表單數(shù)據(jù)

    原生JavaScript實(shí)現(xiàn)批量獲取表單數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了如何使用原生JavaScript實(shí)現(xiàn)批量獲取表單數(shù)據(jù),文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • JavaScript基本語(yǔ)法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    JavaScript基本語(yǔ)法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了JavaScript基本語(yǔ)法,適合剛?cè)腴T(mén)的同學(xué),有興趣的可以了解下。
    2017-06-06

最新評(píng)論