webpack4(03)

管理资源

加载图片

我们使用两种方式引入图片

1:通过css引入
2:通过js引入

加载图片资源我们需要先安装

npm install --save-dev file-loader

修改index.html文件

<!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图片

webpack-demo
    
    /src
+      logo.png  

修改index.js文件如下

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文件如下

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

最后为配置文件新增处理图片的规则

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引入的图片我们怎么处理呢?

安装

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

猜你喜欢

转载自www.cnblogs.com/xqzi/p/10724850.html