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中引入便可,在浏览器中就能够看到效果了。

本站公众号
   欢迎关注本站公众号,获取更多信息