webpack4(03)

管理資源

加載圖片

咱們使用兩種方式引入圖片css

1:經過css引入
2:經過js引入

加載圖片資源咱們須要先安裝html

npm install --save-dev file-loader

修改index.html文件webpack

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <style>
        .hello{
            color: pink;
        }
    </style>
    <body>
        <div class="hello">
            hello,qzy
        </div>
+       <div class="logo"></div>
    </body>
</html>

src目錄下新增logo.png圖片es6

webpack-demo
    
    /src
+      logo.png

修改index.js文件以下web

require('./style.css');
require('./style.scss');
//建立一個元素並引入圖片
import logo from './logo.png';
let element = document.createElement('div');
element.classList.add('js-logo');

// 將圖像添加到咱們現有的 div。
let myIcon = new Image(); 
myIcon.src = logo;
element.appendChild(myIcon);

document.body.appendChild(element)

修改style.css文件以下npm

.hello{
    color: red;
}
.logo{
    width: 200px;
    height: 200px;
    background: url(logo.png) no-repeat pink;
}

最後爲配置文件新增處理圖片的規則json

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        contentBase: './dist',
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new MiniCssExtractPlugin({
            filename:'main.css'//抽離的文件名
        }),
    ],
    module: {
        rules: [{
            test: /\.css$/,
            use: [{
                loader: MiniCssExtractPlugin.loader,
            }, 'css-loader']
        }, {
            test: /\.scss$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader','sass-loader']
        },
    +   {
    +       test: /\.(png|svg|jpg|gif)$/,
    +       use:['file-loader']
    +   }
        ]
    }
}

打包以後咱們能夠發現以下文件
image
咱們的圖片已經被打包出來了。瀏覽器

那麼對於直接在html引入的圖片咱們怎麼處理呢?緩存

安裝sass

npm install html-withimg-loader --save

使用

{
    test: /\.(htm|html)$/,
    loader: 'html-withimg-loader'
}

這樣就能夠處理html文件內引入的圖片了。假如咱們引入了不少圖片,那麼打包的時候就會生成不少文件,咱們引入的時候必然會形成http請求數量不少,下面咱們作一下優化。

安裝

npm install --save-dev url-loader

url-loader 功能相似於 file-loader,可是在文件大小(單位 byte)低於指定的限制時,能夠返回一個 DataURL
安裝成功以後咱們對圖片處理的規則作以下修改。

{
    test: /\.(png|svg|jpg|gif)$/,
    use: [{
        loader: 'url-loader',
        options: {
            limit: 8 * 1024
        }
    }]
}

再次打包咱們發現咱們的圖片被打包成了base64格式文件,js、css文件中都是如此。

url-loader對未設置或者小於limit設置的圖片進行轉換,以base64的格式被使用;而對於大於limit byte的圖片用file-loader進行解析。

既然能夠減小請求,咱們都採用這種方式不能夠嘛

圖片編碼的base64是一大長串,==大小會比原文件大大約三分之一==,圖片太大的話base64字符串會更長,文件就會變得很大,因此還不如用http請求,這也就是爲何默認limit是10000了,就是讓8kb以內的圖片才編碼。並且能夠看到base64的圖片在引入的地方都執行了,加載了屢次,沒有緩存,若是屢次引用的話可想而知。

下面咱們對配置文件修改,讓圖片打包到一個文件下。limit參數修改一下不打包成base64格式,讓其單獨生成

{
    test: /\.(png|svg|jpg|gif)$/,
    use: [{
        loader: 'url-loader',
        options: {
            limit: 6 * 1024,
+           outputPath:'img/'
        }
    }]
}

打包後發現圖片已經被放到指定位置了
image

加載字體

那麼,像字體這樣的其餘資源如何處理呢?file-loader 和 url-loader 能夠接收並加載任何文件,而後將其輸出到構建目錄。這就是說,咱們能夠將它們用於任何類型的文件,包括字體。讓咱們更新 webpack.config.js 來處理字體文件,添加處理字體的規則。

{
    test: /\.(woff|woff2|eot|ttf|otf)$/,
    use: ['file-loader']
}

這樣的話咱們就能夠正常的引入字體了,具體的操做就不作了,能夠去源碼那裏看一下。

加載數據

通常的咱們經常使用的就是json,json是默認支持的。咱們正常的引入使用便可,也不在作演示。

轉化es6語法

下面的代碼是基於上面兩個例子的含有json與字體,根據源碼本身刪減一下便可。
咱們在index.js文件中新增以下代碼

let add=(x,y)=>{
    return x+y
}
console.log(add(3,4));

打包後會發現代碼以下

console.log(((e, n) => e + n)(3, 4)),

箭頭函數沒有被轉化,咱們知道並非全部的瀏覽器都支持es6或者更高級的語法,咱們仍是要將這些高級語法轉化爲es5語法,已達到瀏覽器兼容。
安裝

npm install --save-dev babel-loader @babel/core @babel/preset-env

@babel/core:babel 核心包,編譯器。提供轉換的API
@babel/preset-env:能夠根據配置的目標瀏覽器或者運行環境來自動將不支持的ES2015+的代碼轉換爲es5。
而後修改配置文件,添加新的規則

{
    test: /\.js$/,
    use: [{
        loader:'babel-loader',
        options:{
            presets:['@babel/preset-env']
        }
    }]
}

再次打包就會發現文件變成了這樣

console.log(3 + 4)

由於咱們的mode是生成環境,你能夠切換成開發環境試試效果。
下面咱們在index.js 中新增以下代碼,而後在ie瀏覽器中就報錯了,

let p=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('end');
    },3000)
})
p.then((val)=>{
    console.log(val)
})

咱們不是已經處理過了嘛,這是由於Babel默認只轉換新的JavaScript句法(syntax),而不轉換新的API,好比Promise,Maps,Symbol。
若是想讓這個方法運行,必須使用babel-polyfill,爲當前環境提供一個墊片。

安裝

npm install --save @babel/polyfill

注意此時是 --save,由於這是一個polyfill(它將在您的源代碼以前運行),因此咱們須要它是一個依賴項,而不是開發依賴。

require("babel-polyfill");
//或者
import "babel-polyfill";
//或者
module.exports = {
  entry: ["babel-polyfill", "./app/js"],
};

那咱們直接在index.js中引入便可,在瀏覽器中就能夠看到效果了。

本站公眾號
   歡迎關注本站公眾號,獲取更多信息