• 35648

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

一看就懂之webpack基础配置

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0812/105148.html 1190000020036172

一看就懂之webpack基础配置

一、webpack 简介

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

简单说,webpack可以看做是一个模块打包机,主要作用就是: 分析你的项目结构,找到JavaScript模块以及一些浏览器不能直接运行的拓展语言(sass、less、typescript等),然后将它们打包为合适的格式以供浏览器使用。

webpack主要实现的功能:

代码转换(如: ES6转换ES5、sass和less转换为css等)
文件优化(如: 将模块内容进行压缩)
代码分割(如: 多页面应用公共模块的抽离、路由懒加载)
模块合并(如: 按照不同的功能将多个模块合并为一个模块)
自动刷新(如: 启动本地服务,代码更新后进行自动刷新)
代码校验(如: 添加eslint进行代码规范检查)
自动发布(如: 应用打包完成后,自动发布)

二、webpack 安装

在webpack 3中,webpack本身和它的CLI以前都是在同一个包中的,但在第4版之后,已经将两者分开来更好地管理它们,所以安装webpack4之后的版本,要同时安装webpack和webpack-cli

注意,安装webpack的时候,必须进行本地安装才能生效,否则会报错,如:
图片描述
但是全局安装了也有一个好处,那就是可以在项目根目录下直接执行webpack即可完成项目的打包,如果没有进行全局安装,那么可以通过npx直接执行项目本地安装的模块,即 npx webpack也可以完成项目的打包。

三、webpack 基础配置

webpack是支持零配置的,即不需要配置文件即可完成打包,其默认入口文件为项目根目录下的src目录下的index.js文件,其默认出口为项目根目录下的dist目录的main.js

如果没有给webpack添加配置文件,那么webpack的打包能力就会非常弱,webpack执行的时候默认会加载项目根目录下的webpack.config.js文件,注意,该配置文件是一个js文件,而不是json文件,并且其是通过node去执行的,所以其完全支持node语法,即node中能用的,在配置文件中都可以用
webpack配置文件必须要对外暴露一个对象,即通过module.exports进行对外暴露,其中的所有配置都必须写在这个对外暴露的对象中。

context
context属性表示的是webpack的上下文目录,配置入口文件的时候,如果入口文件使用的是相对路径,那么就是相对于context所在的目录。

context默认值为执行webpack命令时所在的当前工作目录,通常是在项目根目录下执行webpack命令,所以可以认为其值默认为项目根目录,所以如果入口文件路径写成相对路径,最好将context配置成context: path.resolve(__dirname),以防止在非项目根目录下执行webpack命令时找不到入口文件路径而报错。

entry

entry用于配置模块的入口文件,可以配置多个,webpack将从入口文件开始搜索以及递归解析所有入口文件依赖的模块,其是必填的,如果配置文件中没有entry则会报错。entry的属性值可以是表示路径的单个字符串也可以是数组,数组中的元素为入口文件的路径,还可以是对象,对象的属性名为入口文件的chunk名,即打包后输出文件的名字,属性值为入口文件的路径。注意,入口文件的路径可以是绝对路径也可以是相对路径,相对路径默认是以配置文件中的context属性值表示的路径
module.exports = {
    entry: "./foo.js" // 属性值为一个表示路径的字符串
}
其输出结果文件取决于配置文件的output配置,如果output.filename没有配置,则默认输出为main.js,如果output.filename值为指定的名称,则输出结果为output.filename的属性值
module.exports = {
    entry: [ "./foo.js", "./bar.js"] // 属性值为一个数组
}
其输出结果文件也是取决于配置文件的output配置,只不过,其会将foo.js和bar.js一起打包输出为一个文件,如果output.filename没有配置,则默认输出为main.js,如果output.filename值为指定的名称,则输出结果为output.filename的属性值
module.exports = {
    entry: { // 属性值为一个对象
        a: "./src/bar.js",
        b: "./src/foo.js",
        c: "./src/index.js"
    }
}
其输出结果不再取决于output.filename的配置,因为entry已经指定好了模块输出的chunk名,即会分别输出a.js、b.js和c.js三个文件,并且此时output.filename属性值不能配置为一个固定名称的输出文件,因为入口文件有多个,必然输出文件也会有多个
chunk和module的区别,二者都是表示模块,但是module可以看做是具有独立功能的小模块,即小块,也就是打包之前,程序员编写的一个一个的文件,每个文件称为一个module;而chunk则可以看做是由多个小module打包成的大模块,即大块

output
output配置的是如何输出最终想要的代码,output是一个object。

path: 用于配置打包后输出文件的本地存放目录,必须是绝对路径,当然也可以不配置,因为如果没有配置path,那么会自动在执行webpack命令时所在的目录下自动创建dist目录并将打包结果输出到dist目录下,与context的配置路径无关

module.exports = {
    output: {
        path: path.resolve(__dirname, "./dist") // 必须是绝对路径
    }
}

filename: 用于配置输出文件的名称,如果只有一个输出文件,那么可以配置成静态不变的文件名,如:

module.exports = {
    output: {
        filename: "bundle.js"
    }
}

但是,如果有多个chunk要输出时,即入口文件配置了多个时,那么filename就不能配置成静态不变的了,就必须借助模板和变量了,常见的两个变量,如:
[name]: 可以自动获取到入口文件配置的chunk名称;
[hash]: 可以自动生成hash值,hash值的长度是可以指定的,默认为20位;

module.exports = {
    output: {
        filename: "[name][hash:8].js" // 以入口文件设置的chunk作为输出名,并且指定hash值为8位
    }
}

library和libraryTarget: 用于指定将模块的输出结果挂载到哪个地方或者以什么样的方式导出库(模块输出结果)。二者通常要搭配一起使用。
libraryTarget通常用于指定以何种方式导出库,library通常用于指定接收库的名称。
我们将入口的一个或多个js文件打包输出后的结果也是一个js文件,在没有配置library和libraryTarget的时候,这个输出的js文件中包含了一个匿名自执行函数, 即输出文件的执行结果没有被任何东西接收,我们引入输出文件执行后不会得到任何结果。 如:

(function(){
    console.log("foo");
    return "foo"; // 虽然有返回值,但是匿名自执行函数执行完毕后拿不到任何结果
})();
// 我们以var 变量 的方式来接收函数的返回值
var foo = (function(){ // 匿名自执行函数执行完毕后就会将函数返回值保存到foo变量上
    console.log("foo");
    return "foo";
})();
console.log(`foo is ${foo}`);
打包后的输出文件的输出结果(导出结果),就是入口文件的输出结果(导出结果),即入口文件通过export、exports、module.exports等输出(导出)的结果

var: 将libraryTarget设置为var, 同时指定一个自定义的变量名来接收模块的输出,这个自定义的变量名就是library的属性值

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "var",
        library: "test"
    }
}

模块的输出结果将会赋值给test变量,其输出文件bundle.js内容大致如下:

var test = (function(modules){
    return result; // 返回值result将会被赋值给test变量 
})();

commonjs: 将libraryTarget设置为commonjs, 即通过commonjs规范导出,同时指定一个自定义的变量名来接收模块的输出,这个自定义的变量名就是library的属性值, 只不过这个自定义的变量名是exports的属性名,如:

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "commonjs",
        library: "test"
    }
}

模块的输出结果将会赋值给exports["test"]上,其输出文件bundle.js内容大致如下:

exports["test"] = (function(modules){
    return result; // 返回值result将会被赋值给exports["test"]
})();

commonjs2: 将libraryTarget设置为commonjs2,即通过commonjs2规范导出,此时library的配置将无意义,因为commonjs2的输出是固定的module.exports,所以不需要指定library了,如:

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "commonjs2"
    }
}

模块的输出结果将会被赋值到module.exports上,其输出文件bundle.js内容大致如下:

module.exports = (function(modules){
    return result; // 返回值result将会被赋值给module.exports
})();
commonjs和commonjs2的区别在于,commonjs只能使用exports进行导出,而commonjs2在commonjs的基础上增加了module.exports进行导出;

this: 将libraryTarget设置为this, 那么此时library配置的变量名将作为this的属性名来接收模块的导出结果,如:

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "this",
        library: "test"
    }
}

模块的输出结果将会被赋值到this["test"] 上,其输出文件bundle.js内容大致如下:

this["test"] = (function(modules){
    return result; // 返回值result将会被赋值给this["test"]
})();

同理libraryTarget的属性值还可以是windowglobal,这里就不一一列举了。

publicPath
publicPath用于配置打包资源发布到线上时服务器的url地址,打包完成后,html文件中如果引入了js、image、css等资源,那么都会在前面加上publicPath所表示的路径

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        publicPath: "http://www.lihb.com/"
    }
}

// index.html

<!DOCTYPE html>
<html lang="en">
<body>
    <script type="text/javascript" src="/uploads/allimg/190812/1000335958-2.jpg"></script></body>
</html>

四、webpack 打包输出后的内容分析

webpack打包输出后的结果默认是一个匿名自执行函数,匿名自执行函数传递的参数为一个对象,对象的属性名为入口文件的路径名属性值为一个函数,函数体内部通过会执行eval(),eval()方法的参数为入口文件的内容字符串,而这个匿名自执行函数,内部有一个自定义的__webpack_require__方法,该方法需要传入入口文件的路径名作为参数,匿名自执行函数执行完成后会返回__webpack_require__的结果,而__webpack_require__()方法内部执行的时候,会首先创建一个module对象module对象里面有exports属性,属性值为一个空的对象,用于接收入口文件的模块输出,如:

(function(modules) {
    function __webpack_require__(moduleId) { // 传入入口文件的路径
        var module = installedModules[moduleId] = { // 创建一个module对象
             i: moduleId,
             l: false,
             exports: {} // exports对象用于保存入口文件的导出结果
         };
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 执行入口文件
        return module.exports; // 返回模块输出结果
    }
    return __webpack_require__(__webpack_require__.s = "./src/bar.js"); // 返回入口文件
})({
     "./src/bar.js": (function(module, exports) {
         eval("module.exports = \"bar\";");
     })
  });
所以不管入口文件是以ES6模块的方式输出还是以commonjs模块的方式输出,最终入口文件的模块输出结果都会被绑定到__webpack_require__方法中定义的module对象的exports属性上,只不过,如果是以commonjs的方式输出,那么入口文件的输出结果将会直接替换掉__webpack_require__方法中定义的module对象的exports属性;如果是以ES6模块的方式输出,则是在__webpack_require__方法中定义的module对象的exports属性值中添加一个default属性或者具体变量名来保存入口文件的输出

五、webpack 本地服务器配置

为了更方便调试,我们需要用到webpack的本地http服务器功能,要想使用webpack提供的Web服务器功能,我们需要安装webpack-dev-server模块,webpack-dev-server会启动一个web服务器用于实现网页请求,也可以监听文件的变化自动刷新网页。

webpack-dev-server模块安装完成后,我们可以在项目根目录下运行npx webpack-dev-server,其和webpack命令一样,如果没有配置文件,则使用内置默认配置进行打包输出,如果有则使用配置文件中的配置,只不过其不会将打包结果输出到指定的目录中,因为webpack-dev-server会忽略配置文件中的output.path配置,其会将打包输出结果保存到内存中。webpack-dev-server启动后会默认将启动devServer时所在的目录作为根目录,即执行npx webpack-dev-server命令时所在的目录

webpack提供了一个devServer属性用于配置启动的服务器的一些参数,当然webpack本身是无法识别devServer属性配置的,只有通过webpack-dev-server去启动webpack时,devServer的配置才会生效

module.exports = {
    devServer: {
        port: 3000, // 让devServer监听3000端口
        contentBase: "./dist", // 将当前项目的dist目录作为devServer的根目录
        progress: true, // 显示打包进度条
        compress: true // 是否启用Gzip压缩,默认为false
    }
}
webpackDevServer启动后,默认会自动监听打包源文件的变化,如果修改了打包源文件,那么会自动重新打包到内存,并且会自动刷新浏览器,但是自动刷新浏览器功能必须将target设置成web,否则自动刷新功能将会失效,比如target为node就无法起作用。

六、webpack 插件配置

在不使用插件的时候,webpack默认只能打包输出js文件,如果我们想要输出其他格式的文件到输出目录中,那么我们必须使用插件。webpack提供了一个plugins属性用于配置使用到的插件,其属性值为一个数组,数组中的元素为插件对象,通常插件都是一个类,我们需要通过插件类来创建一个插件对象
html-webpack-plugin
该插件可以指定一个html文件,webpack会将该html文件打包输出到输出目录中,同时会将打包输出后的文件自动插入到该html文件中,即让该html文件自动引入打包后的js文件

module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html", // 要打包输出哪个文件,可以使用相对路径
            filename: "index.html", // 打包输出后该html文件的名称
            minify: {
                removeAttributeQuotes: true, // 去除html文件中的引号
                collapseWhitespace: true // 合并空格,即将html进行单行显示
            },
            hash: true // 向html文件中引入打包后的js时候带上hash值
        })
    ]
}
html插件中配置了hash为true, 是在引入打包后的js的时候带上hash值,如:
<script type="text/javascript" src="main.js?c7086a400fa368e84ad6"></script></body>

七、webpack 模块配置

webpack默认将所有格式的文件都当做模块进行处理,但是wepback默认只能处理js模块。如果在js中通过require引入了其他格式的模块(文件),那么webpack就必须通过安装合适的模块加载器,才能正确解析对应的模块内容,webpack提供了一个module属性,用于进行模块解析器的配置,其属性值为一个对象,对象中有一个rules属性,其属性值为一个数组,数组中的元素为一个对象,该对象主要完成两件事,匹配对应格式的文件,并且使用对应模块加载器进行加载,匹配使用的是test属性,属性值为一个正则表达式,【使用】使用的是use属性,属性值可以是字符串也可以是数组,如果只有一个模块加载器的时候,可以使用字符串的形式,如果有多个模块加载器的时候,那么就需要使用数组的形式,当然,如果模块加载器需要传递参数配置,那么可以将模块加载器写成对象的形式,通过loader属性指定模块加载器名称,通过options属性传递参数配置。

① 处理css样式,需要使用到css-loader和style-loader。
首先需要安装css-loader和style-loader。
css-loader必须同时和style-loader一起使用才能正确加载css文件,一个负责加载,一个负责插入css-loader负责加载css, 即在js文件中能够通过require的方式引入css,即加载和解析css,同时支持在css文件中使用@ import的方式引入其他css文件style-loader负责将加载并解析好的css文件插入到html文件中去,从名字可以看出其是在html文件中生成style标签来引入css文件,loader的执行顺序是从右向左,所以必须先加载然后再插入

比如,打包入口文件index.js中通过require的方式引入了一个index.js文件,即require("./index.css"),那么webpack需要进行如下配置:

module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/, // 匹配以.css结尾的文件
                use: [ // 并交给css-loader和style-loader进行处理
                    {
                        loader: "style-loader", // 以对象的形式配置loader
                        options: { // 通过options给loader传递参数
                            insertAt: 'top' // 默认为bottom, 将加载的css文件插入到head标签的最上面,即优先级最低,会被覆盖
                        }
                    },
                    "css-loader" // 直接以字符串的形式配置loader
                ]
            }
        ]
    }
}
打包输出后,会将index.css中的内容放到<style>标签中,并且将这个<style>标签自动插入到index.html文件的<head>标签的最底部,如果配置了insertAt: "top", 那么就会插入到<head>标签的最上面。
同理,我们也可以出来sass,即scss文件,要处理scss文件,我们需要安装sass-loader,而sass-loader需要配合node-sass一起使用,安装好sass-loader之后我们只需要再添加一个rule,改成匹配.scss结尾的模块,处理sass和处理css都需要用到style-loader和css-loader,只不过处理sass还需要sass-loader,即需要用sass-loader将scss文件转换为css文件,在css-loader后加一个sass-loader即可。

八、webpack 样式的高级处理

抽离样式
我们通过css-loader和style-loader处理css样式后是直接通过<style>标签将解析后样式插入到了html中,如果需要将css样式抽离成一个单独的css文件, 并且自动link进html文件中,那么就需要mini-css-extract-plugin这个插件。

首先安装mini-css-extract-plugin插件,然后创建插件对象,并进行相应的配置,主要就是filename,即抽离出的css文件叫什么名字
module.exports = {
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/index.css", // 抽离出的css文件叫什么名字,前面可加路径
        })
    ]
}
filename属性值中可以添加上一个路径,实现css资源的分类输出,上面index.css文件就会输出到输出目录下的css目录下
插件安装配置好之后还不行,因为还要对loader进行相应的配置,之前css文件是通过了style-loader处理的,而style-loader会将样式通过<style>标签的方式插入到html文件中,所以必须先移除style-loader,然后使用mini-css-extract-plugin这个插件提供的loader
module.exports = {
    module: {
        rules: [
            {
                test: /\.css$/, // 匹配以.css结尾的文件
                use: [ // 并交给css-loader和MiniCssExtractPlugin的loader进行处理
                    MiniCssExtractPlugin.loader, // 将css进行抽离
                    "css-loader" // 直接以字符串的形式配置loader
                ]
            },
        ]
    }
}

压缩css
要想压缩css,那么需要用到optimize-css-assets-webpack-plugin插件,需要注意的是该插件并不是配置到plugins属性中,而是配置到optimization属性中

module.exports = {
    optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({})], // 压缩css
    }
}
我们可以通过修改mode为production来压缩我们的js,但是当使用了optimize-css-assets-webpack-plugin插件后,那么js的压缩就会失效,我们需要使用uglifyjs-webpack-plugin插件进行压缩,如:
module.exports = {
    optimization: {
        minimizer: [
            new OptimizeCSSAssetsPlugin({}), // 压缩css
            new UglifyjsWebpackPlugin({ //压缩js
                cache: true,
                parallel: true,
                sourceMap: true
            })
        ], 
    }
}
使用uglifyjs-webpack-plugin插件后,mode的切换仍然是生效的了。

九、webpack JS的高级处理

① 将ES6以上的高级语法特性转换ES5
Babel是一个JavaScript的编译器,能将ES6的代码转换为ES5的代码,我们需要安装babel-loader来处理我们js文件,而其需要配合@babel/core模块一起使用,还要告诉babel当前要转换的JS代码中使用了哪些新特性,即预设,我们使用包含当前所有最新ES语法特性的预设即可,@babel/preset-env

module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    {
                        loader: "babel-loader", // 使用babel-loader进行处理js文件
                        options: {
                            presets: ["@babel/preset-env"] // 用了最新的ES6语法预设
                        }
                    }
                ]
            }
        ]
    }
}

② 减少代码冗余
babel在转换ES6语法的时候,会使用一些由ES5编写的帮助函数来实现新语法的转换。比如转换class语法,就需要使用到classCallCheck()函数,如果多个文件中都使用到了Class语法,那么每个文件都会被注入classCallCheck()辅助函数,代码就会变得非常冗余,通过引入@babel/babel-plugin-transform-runtime插件就可以在输出文件中通过require的方式引入一个公共的classCallCheck()辅助函数,然后所有文件一起使用即可减少代码的冗余。@babel/babel-plugin-transform-runtime插件需要配合@babel/runtime一起使用,因为babel-plugin-transform-runtime插件引入的帮助函数,都存放在@babel/runtime中

module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    {
                        loader: "babel-loader", // 使用babel-loader进行处理js文件
                        options: {
                            presets: ["@babel/preset-env"] // 用了最新的ES6语法预设
                            plugins: ["@babel/plugin-transform-runtime"] // 减少代码冗余插件
                        }
                    }
                ]
            }
        ]
    }
}

③ 转换新的ES6API
babel默认只能转换ES6的新语法,如果想要转换一下ES6的新功能(Promise)、新接口(数组的includes方法)等,那么需要使用到@babel/polyfill, 其工作原理是在全局对象或者内置对象中添加一下属性或者方法,其使用方式为: 一种是直接在js文件中require, 如: require("@babel/polyfill"); 另一种是将"@babel/polyfill"作为入口文件一起打包成一个chunk,如:

module.exports = {
    entry: ['@babel/polyfill', "./src/index.js"] 
}
比如,使用了Promise,那么打包输出的文件中,可以看到全局对象global被添加了一个Promise属性

十、webpack 第三方模块的处理

① 如果我们的项目中使用到了第三方模块,比如jquery,我们直接在我们的js模块中引入jquery,那么这个jquery只能在当前模块中使用,而无法暴露到全局变量window中,如果想要实现,自动将jquery暴露给全局变量,那么需要引入expose-loader,其可以作为内联loader直接在js中使用,也可以作为普通loader在配置文件中使用。
// index.js

import $ from "expose-loader?$!jquery";
console.log($);
console.log(window.$); // 可以获取到jquery

或者在配置文件中引入

module.exports = {
    module: {
        rules: [
            {
                test: require.resolve("jquery"), // 如果require的时候引入了jquery
                use: "expose-loader?$" // 那么将$变量暴露到全局
            }
        ]
    }
}
expose-loader是将一个模块的输出暴露给全局变量(不限于第三方模块,任何模块都可以),但是具体是暴露给window和global取决于配置文件中target的配置,如果是node则暴露给global,如果是web则暴露给window

② 我们也可以不直接在我们的js文件中引入第三方模块,就可以使用他们,可以通过webpack提供的providePlugin内置插件来实现,将第三方模块注入到每个模块中,当然也可以是其他任何一个模块,如:

new webpack.ProvidePlugin({
            $: "jquery",
            foo: path.resolve(__dirname,"./src/foo.js") // 自定义模块必须是模块的绝对路径否则无法解析
        })
我们就可以在任何一个模块中使用$和foo变量了,因为他们被注入到了所有模块中,但是全局变量中是无法访问到的

③ 以上两种方式第三方模块都会被打包输出到我们的最终输出文件中,我们通常是不希望将第三方模块打包到我们的输出文件中的,因为会我们可以通过cdn的方式直接引入第三方模块,这个时候我们就需要告诉webpack哪些模块不需要打包输出,并且用运行环境中的全局变量进行替换,需要用到webpack提供的externals配置,如:

module.exports = {
    externals: {
        "jquery": "jQuery" // 排除jquery模块打包,并用浏览器中的jQuery替换掉jquery
    }
}
此时虽然js模块中引入了jquery,但是也不会被打包到输出文件中,并且html模板文件中直接通过cdn引入了jQuery,所以全局变量中也可以直接访问到jQuery

十一、webpack 图片的处理

webpack是将所有文件都当做模块进行处理的,所以图片也被认为是一个模块,需要通过require或者import进行引入加载才能被正确打包输出。
如果想要加载并解析图片模块,那么必须使用合适的loader,解析图片可以使用file-loaer。如:

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|jpg|gif)$/, 
                use: "file-loader" // 用file-loader解析图片模块
            }
        ]
    }
}
图片会被单独打包出来放在输出目录中,但是输出的图片名称会发生变化,以hash值作为图片文件名,如果在css文件中使用图片,不需要通过require的方式,可以直接通过url("图片路径")的方式,因为css-loader对url()进行了转换,会转换为require的方式

如果想在html文件中直接使用<img/> 标签引入图片,那么需要使用到html-withimg-loader来处理我们的html文件,图片同样会被打包单独输出到输出目录中。

module.exports = {
    module: {
        rules: [
            {
                test: /\.html$/, // 处理html文件
                use: {
                    loader: "html-withimg-loader",
                    options: {
                        min: false // 不去除html中的换行符
                    }
                }
            }
        ]
    }
}

如果想将图片打包成base64编码格式,那么需要使用到url-loader来处理我们的图片url-loader其实包含了file-loader的功能,因为其可以设置一个limit,限制图片的大小,只有图片的大小在limit范围内才会被打包为base64编码格式,超过limit则还是单独打包图片到输出目录中

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|jpg|gif)$/, 
                use: {
                    loader: "url-loader", // 用url-loader解析图片模块
                    options: {
                        limit: 200 * 1024, // 限制图片大小为200kb内才打包为base64编码格式
                        outputPath: "/img/", // 将图片打包输出到输出目录的img目录下
                        publicPath: "http://www.lihb.com/" // 仅仅给输出的图片资源添加资源服务器存放地址
                    }
                }
            }
        ]
    }
}
url-loader可以配置一个outputPath将图片输出到指定目录下面,实现资源的分类输出。还可以配置一个publicPath,在引入图片资源的时候添加上图片资源所在的服务器地址。

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!