首頁 >web前端 >js教程 >webpack的樣式載入詳解

webpack的樣式載入詳解

php中世界最好的语言
php中世界最好的语言原創
2018-03-16 14:30:571804瀏覽

這次帶給大家webpack的樣式載入詳解,webpack樣式載入的注意事項有哪些,下面就是實戰案例,一起來看一下。

載入css需要用到css-loader和style-loader css-loader將@import 和url 處理成正規的ES6 import ,如果@import指向的是一個外部資源,css-loader會跳過,而只會對內部資源做處理。 css-loader處理之後,style-loader會將輸出的css注入到打包檔案中。 css預設是inline模式,且實作了HMR介面。但inline不太適用於生產環境(全部輸出在頁面上)。還需要用extracttextplugin產生一個單獨的css文件,但先一步一步來。

一,樣式打包

1.安裝css-loader,style-loader

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

2.修改webpack.config.js

增加一個一層級子節點

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

test的正規則會符合.css的檔案。 use中的執行順序是從右到左。 loader的執行是連續的,就像管道一樣,先到css-loader再到style-loader。 loaders: ['style-loader', 'css-loader'] 可以理解為:styleloader(cssloader(input)) 。

3.新增樣式

app/mian.css

body {
  background: cornsilk;
}

然後在index.js中引入

import './main.css';

再執行npm start,在http: //localhost:8080/中開啟

這時候頁面出現了背景色,而且發現樣式寫入了header中,這個時候你改變顏色,介面也會無刷新的更新,這正是上一節HMR的效果。

樣式也是透過webpackHotUpdate方法來更新。

二、載入less

再看如何載入less,先安裝less-loader

npm install less less-loader --save-dev

再修改設定檔

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

然後建立一個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%);
  p { .box-shadow(0 0 5px, 30%) }}
body {
  background: cornsilk;
}

修改index.js

 import  './less.less';
 import component from './component';var ele=document.createElement("p");
ele.innerHTML="this is an box";
ele.className="box";
document.body.appendChild(ele);
let demoComponent=component();
document.body.appendChild(demoComponent);

得到效果:

可以看見編譯成功,要注意的是,再使用less的時候import只能是less文件,這時候再import main.css會報錯。這一節對less就做一個簡單的演示,其他樣式預處理同理,下面的內容還是繼續基於css。

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

 一般來說css的作用域都是全局的,我們常在母版頁裡面添加了多個樣式文件,後面的樣式文件會覆蓋前面的樣式文件,常常給我們的調試帶來麻煩。而CSS Modules透過import引入了本地作用域。這樣能夠避免命名空間衝突。 webpack的css-loader是支援CSS Modules的,該怎麼理解呢,先看幾個例子。我們先在設定中開啟(先關掉HMR):

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

然後定義一個新的樣式(main.css):

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

給component加一個樣式,先引入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;
}

這時候我們看到介面已經改變了。

 再看右邊產生的樣式,我們的樣式名稱已經改變了。回顧整個過程相當於main.css中的每一個類別名稱成了一個模組,在js中可以像取得模組一樣的取得。但是你可能會想,為毛我不能直接給元素賦值,幹嘛要import呢。這是個好問題,我們再新增一個樣式

不同樣式檔的同名類別

other.css

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

它也有一個.redbutton的類別(但效果是紫色的),然後在index.js中建立一個p元素並給它添加redbutton樣式。

import './main.css';import styles from './other.css';import component from './component';var ele=document.createElement("p");
ele.innerHTML="this is an other button";ele.className=styles.redButton;document.body.appendChild(ele);
let demoComponent=component();
document.body.appendChild(demoComponent);

再看效果

#

上面这个图说明了两问题,一个是我们在index.js中引入了2个样式文件,在index页面就输出了两个style,这让人有点不爽,但我们后面再解决。另外一个就是虽然两个样式文件中都有redButton这个类,但是这两者还是保持独立的。这样就避免了命名空间的相互干扰。如果你这个时候直接赋值

element.className="redButton";

这样是获取不到样式的。直接对元素的样式默认是全局的。

全局样式

如果想让某个样式是全局的。可以通过:global来包住。

other.css

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

main.css

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

这个时候redbutton这两个样式就会合并。需要直接通过样式名来获取。

 element.className="redButton";

组合样式

我们再修改other.css,创建一个shadowButton 样式,内部通过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("p");
ele.innerHTML="this is an shadowButton button";console.log(styles);
ele.className=styles.shadowButton;
document.body.appendChild(ele);

看一下是什么效果:

日志打印出来的是styles对象,它包含了两个类名。可以看见shadowButton是由两个类名组合而成的。p的class和下面的对应。

 四、输出样式文件

css嵌在页面里面不是我们想要的,我们希望能够分离,公共的部分能够分开。extracttextplugin 可以将多个css合成一个文件,但是它不支持HMR(直接注释掉hotOnly:true)。用在生产环境挺好的

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

先安装extracttextplugin这个插件,然后再webpack.config.js中进行配置:

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
  ],
}

一开始看到这个配置,让人有点懵。首先看fileName,表示最后输出的文件按照这个格式'[name].[contenthash:8].css',name默认是对应的文件夹名称(这里是app),contenthash会返回特定内容的hash值,而:8表示取前8位。当然你也可以按照其他的格式写,比如直接命名:

new ExtractTextPlugin('style.css')

而ExtractTextPlugin.extract本身是一个loader。fallback:'style-loader'的意思但有css没有被提取(外部的css)的时候就用style-loader来处理。注意到现在我们的index.js如下:

import  './main.css';
import styles from './other.css';
import component from './component';var ele=document.createElement("p");
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;
    })
}

View Code

引入了两个css文件。

这个时候我们执行 npm run build

再看文件夹得到一个样式文件。(如果不想看到日志可以直接npm build)

 

但是我们在第三部分使用了CSS Modules,发现other.css的样式没有打包进来。所以,我们的webpack.config.js还要修改:

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

再次build。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

JS事件先发布后订阅的方法

vue2全家桶是什么,如何使用?

vue的自定义动态组件使用详解


以上是webpack的樣式載入詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn