webpack4-用之初体验,一起敲它十一遍

2024-01-16 09:48

本文主要是介绍webpack4-用之初体验,一起敲它十一遍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章 | https://juejin.im/post/5adea0106fb9a07a9d6ff6de

众所周知,webpack进入第4大版本已经有一段的时间了,而且webpack团队升级更新的速度也是非常的惊人。

在写下如下内容的时候webpack已经出到了4.6的版本了,剑指5.0应该是指日可待了,当然这些都是个人的臆想,并不代表任何意见。

既然我们已经迎接了webpack4的到来了,那么就一起来使用一下,即使你没用过之前的版本,没关系,我们重新出发,将工作中常用到的配置写给大家来看

非友情提示:由于webpack使用起来并不能仅看代码就方便理解,所以有图有真相的才是正解,于是乎本文配图很多,真的是很多

首先,既来之,则安之

安装webpack

  • 需要先在项目中npm init初始化一下,生成package.json

  • 建议node版本安装到8.2以上


// webpack4中除了正常安装webpack之外,需要再单独安一个webpack-clinpm i webpack webpack-cli -D

★ npm i -D 是 npm install --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies中,主要在开发环境中的依赖包

0配置了什么

webpack4可以支持0配置打包,这里所说的0配置又是什么呢?当然在开发者眼中0配置的东西,那根本是无法用的,因为不够智能,那么我们就来看看做到了哪些0配置

在使用webpack进行打包的时候,默认情况下会将src下的入口文件(index.js)进行打包


// node v8.2版本以后都会有一个npx// npx会执行bin里的文件
npx webpack     // 不设置mode的情况下 打包出来的文件自动压缩
npx webpack --mode development  // 设置mode为开发模式,打包后的文件不被压缩

当执行npx webpack命令的时候,webpack会自动查找项目中src目录下的index.js文件,然后进行打包,生成一个dist目录并存在一个打包好的main.js文件

这些算是0配置的操作了,名字都是定义好的,不能变,想想也很鸡肋。

webpack的使用还是在我们的配置方面,下面就进入我们的常规操作环节

webpack是基于Node的

在项目下创建一个webpack.config.js(默认,可修改)文件来配置webpack


module.exports = {    entry: '',               // 入口文件    output: {},              // 出口文件    module: {},              // 处理对应模块    plugins: [],             // 对应的插件    devServer: {},           // 开发服务器配置    mode: 'development'      // 模式配置}

以上就是webpack的正常配置模块

★ 启动devServer需要安装一下webpack-dev-server

npm i webpack-dev-server -D

按照项目的结构,我们就从0开始去写一下配置吧


// webpack.config.js
const path = require('path');
module.exports = {    entry: './src/index.js',    // 入口文件    output: {        filename: 'bundle.js',      // 打包后的文件名称        path: path.resolve('dist')  // 打包后的目录,必须是绝对路径    }}

上面就可以说是实现了最简单的webpack配置了,那接下来就打包一下看看。

配置执行文件

工作当中我们打包编译的时候一般都执行npm run dev这样的命令,既然是通过npm执行的命令,我们就应该找到package.json里的执行脚本去配置一下命令,这里如下图所示。

npm run build就是我们打包后的文件,这是生产环境下,上线需要的文件

npm run dev是我们开发环境下打包的文件,当然由于devServer帮我们把文件放到内存中了,所以并不会输出打包后的dist文件夹

通过npm run build之后会生成一个dist目录文件夹,就和上面打包后的样子一样了

多入口文件

多个入口可以有两种实现方式进行打包

  • 一种是没有关系的但是要打包到一起去的,可以写一个数组,实现多个文件打包

  • 另一种就是每一个文件都单独打包成一个文件的

  • 下面就来看看这两种方式的写法


let path = require('path');
module.exports = {    // 1.写成数组的方式就可以打出多入口文件,不过这里打包后的文件都合成了一个    // entry: ['./src/index.js', './src/login.js'],    // 2.真正实现多入口和多出口需要写成对象的方式    entry: {        index: './src/index.js',        login: './src/login.js'    },    output: {        // 1. filename: 'bundle.js',        // 2. [name]就可以将出口文件名和入口文件名一一对应        filename: '[name].js',      // 打包后会生成index.js和login.js文件        path: path.resolve('dist')    }}

这时候执行npm run build后,会生成打包好的两个js文件,如图所示。

配置Html模板

文件都打包好了,但是我们在使用的时候不能在dist目录下去创建一个html文件,然后去引用打包后的js吧,这不合理,实际开发中也不会这样。

我们需要实现html打包功能,可以通过一个模板实现打包出引用好路径的html来。

这就需要用到一个常用的插件了,html-webpack-plugin,用之前我们来安一下它。

npm i html-webpack-plugin -D

因为是个插件,所以需要在config.js里引用一下的。


let path = require('path');// 插件都是一个类,所以我们命名的时候尽量用大写开头let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {    entry: './src/index.js',    output: {        // 添加hash可以防止文件缓存,每次都会生成4位的hash串        filename: 'bundle.[hash:4].js',        path: path.resolve('dist')    },    plugins: [        // 通过new一下这个类来使用插件        new HtmlWebpackPlugin({            // 用哪个html作为模板            // 在src目录下创建一个index.html页面当做模板来用            template: './src/index.html',            hash: true, // 会在打包好的bundle.js后面加上hash串        })    ]}

通过上面的配置后,我们再npm run build打包看一下现在是个什么样子了。

多页面开发,怎么配置多页面

如果开发的时候不只一个页面,我们需要配置多页面,那么需要怎么来搞呢?不用担心,html-webpack-plugin插件自有办法,我们来观望一下。


let path = require('path');let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {    // 多页面开发,怎么配置多页面    entry: {        index: './src/index.js',        login: './src/login.js'    },    // 出口文件      output: {                               filename: '[name].js',        path: path.resolve('dist')    },    plugins: [        new HtmlWebpackPlugin({            template: './src/index.html',               filename: 'index.html',            chunks: ['index']   // 对应关系,index.js对应的是index.html        }),        new HtmlWebpackPlugin({            template: './src/login.html',            filename: 'login.html',            chunks: ['login']   // 对应关系,login.js对应的是login.html        })    ]}

继续npm run build看打包后的样子

上面基本介绍完了html和js的打包配置了,现在我们还缺一个好兄弟css,webpack对css的解析需要用到loader,所以我们先提前安装好,待会好方便使用。

引用CSS文件

可以在src/index.js里引入css文件,到时候直接打包到生产目录下

需要下载一些解析css样式的loader


npm i style-loader css-loader -D// 引入less文件的话,也需要安装对应的loadernpm i less less-loader -D

下面我们来看一下如何配置css文件的解析


// index.jsimport './css/style.css';   // 引入cssimport './less/style.less'; // 引入less
console.log('这里是打包文件入口-index.js');
// webpack.config.jsmodule.exports = {    entry: {        index: './src/index.js'    },    output: {        filename: 'bundle.js',        path: path.resolve('dist')    },    module: {        rules: [            {                test: /\.css$/,     // 解析css                use: ['style-loader', 'css-loader'] // 从右向左解析                /*                     也可以这样写,这种方式方便写一些配置参数                    use: [                        {loader: 'style-loader'},                        {loader: 'css-loader'}                    ]                */            }        ]    }}

  • 此时打包后的css文件是以行内样式style的标签写进打包后的html页面中,如果样式很多的话,我们更希望直接用link的方式引入进去,这时候需要把css拆分出来

  • extract-text-webpack-plugin插件相信用过的人都知道它是干什么的,它的功效就在于会将打包到js里的css文件进行一个拆分

拆分CSS


// @next表示可以支持webpack4版本的插件npm i extract-text-webpack-plugin@next -D

let path = require('path');let HtmlWebpackPlugin = require('html-webpack-plugin');// 拆分css样式的插件let ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
module.exports = {    entry: './src/index.js',    output: {        filaneme: 'bundle.js',        path: path.resolve('dist')    },    module: {        rules: [            {                test: /\.css$/,                use: ExtractTextWebpackPlugin.extract({                    // 将css用link的方式引入就不再需要style-loader了                    use: 'css-loader'                })            }        ]    },    plugins: [        new HtmlWebpackPlugin({            template: './src/index.html',        }),        // 拆分后会把css文件放到dist目录下的css/style.css        new ExtractTextWebpackPlugin('css/style.css')    ]}

此时拆分完css后,打包的html页面就以link的方式去引入css了,这样很好。

当然大家很多都说另外一个插件也是可以办到的,那就是mini-css-extract-plugin,是的可以说它是为webpack4而生的,而之所以上来就没有介绍是因为还不成熟,还有很多bug需要去解决的。

不过既然大家都知道它,那就顺便也提一下吧

npm i mini-css-extract-plugin -D

使用起来和上面的插件是差不多的


let MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {    module: {        rules: [            {                test: /\.css$/,                use: [MiniCssExtractPlugin.loader, 'css-loader']            }        ]    },    plugins: [        new MiniCssExtractPlugin({            filename: 'css/a.css'   // 指定打包后的css        })    ]}

拆分成多个css

这里要着重说一下上面两个插件的区别了,我个人还是建议用extract-text-webpack-plugin的,毕竟从之前的版本承接下来的,虽然在安包的时候需要@next,但是还是值得信赖的

而且现在的extract-text-webpack-plugin也支持了拆分成多个css,而目前mini-css-extract-plugin还不支持此功能


// 正常写入的lesslet styleLess = new ExtractTextWebpackPlugin('css/style.css');// resetlet resetCss = new ExtractTextWebpackPlugin('css/reset.css');
module.exports = {    module: {        rules: [            {                test: /\.css$/,                use: resetCss.extract({                    use: 'css-loader'                })            },            {                test: /\.less$/,                use: styleLess.extract({                    use: 'css-loader'                })            }        ]    },    plugins: [        styleLess,        resetCss    ]}

通过这样操作后可以打包成两个不同的css文件,如下图

引用图片

  • 处理图片方面,也需要loader

npm i file-loader url-loader -D

如果是在css文件里引入的如背景图之类的图片,就需要指定一下相对路径


module.exports = {    module: {        rules: [            {                test: /\.css$/,                use: ExtractTextWebpackPlugin.extract({                    use: 'css-loader',                    publicPath: '../'                })            },            {                test: /\.(jpe?g|png|gif)$/,                use: [                    {                        loader: 'url-loader',                        options: {                            limit: 8192,    // 小于8k的图片自动转成base64格式,并且不会存在实体图片                            outputPath: 'images/'   // 图片打包后存放的目录                        }                    }                ]            }        ]    }}

在css中指定了publicPath路径这样就可以根据相对路径引用到图片资源了,如下图所示。

页面img引用图片

页面中经常会用到img标签,img引用的图片地址也需要一个loader来帮我们处理好

npm i html-withimg-loader -D

module.exports = {    module: {        rules: [            {                test: /\.(htm|html)$/,                use: 'html-withimg-loader'            }        ]    }}

这样再打包后的html文件下img就可以正常引用图片路径了。

引用字体图片和svg图片

字体图标和svg图片都可以通过file-loader来解析


module.exports = {    module: {        rules: [            {                test: /\.(eot|ttf|woff|svg)$/,                use: 'file-loader'            }        ]    }}

这样即使样式中引入了这类格式的图标或者图片都没有问题了,img如果也引用svg格式的话,配合上面写好的html-withimg-loader就都没有问题了

添加CSS3前缀

通过postcss中的autoprefixer可以实现将CSS3中的一些需要兼容写法的属性添加响应的前缀,这样省去我们不少的时间

由于也是一个loader加载器,我们也需要先安装一下

npm i postcss-loader autoprefixer -D

安装后,我们还需要像webpack一样写一个config的配置文件,在项目根目录下创建一个postcss.config.js文件,配置如下:


module.exports = {    plugins: [require('autoprefixer')]  // 引用该插件即可了}

然后在webpack里配置postcss-loader


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

转义ES6

在实际开发中,我们在大量的使用着ES6及之后的api去写代码,这样会提高我们写代码的速度,不过由于低版本浏览器的存在,不得不需要转换成兼容的代码,于是就有了常用的Babel了。

Babel会将ES6的代码转成ES5的代码。

那么不再多说,既然要使用它,就先来安一下。

npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 -D

当把这些都安好后,我们就开始配置,由于要兼容的代码不仅仅包含ES6还有之后的版本和那些仅仅是草案的内容,所以我们可以通过一个.babelrc文件来配置一下,对这些版本的支持。


// .babelrc{    "presets": ["env", "stage-0"]   // 从右向左解析}

我们再在webpack里配置一下babel-loader既可以做到代码转成ES5了。


module.exports = {    module: {        rules: [            {                test:/\.js$/,                use: 'babel-loader',                include: /src/,          // 只转化src目录下的js                exclude: /node_modules/  // 排除掉node_modules,优化打包速度            }        ]    }}

在我们每次npm run build的时候都会在dist目录下创建很多打好的包,如果积累过多可能也会混乱。

所以应该在每次打包之前将dist目录下的文件都清空,然后再把打好包的文件放进去。

这里提供一个clean-webpack-plugin插件

npm i clean-webpack-plugin -D

let CleanWebpackPlugin = require('clean-webpack-plugin');module.exports = {    plugins: [        // 打包前先清空        new CleanWebpackPlugin('dist')    ]}

启动静态服务器

启动一个静态服务器,默认会自动刷新,就是说你对html,css,js文件做了修改并保存后,浏览器会默认刷新一次展现修改后的效果。

正常情况下我们都是在开发环境中开发项目,所以之前配置的脚本"dev"可以派上用场了,在执行npm run dev命令后,会启动静态服务器,我们访问localhost:3000端口就可以看到开发的页面内容了。

如果devServer里open设为true后,会自动打开浏览器。


module.exports = {    devServer: {        contentBase: './dist',        host: 'localhost',      // 默认是localhost        port: 3000,             // 端口        open: true,             // 自动打开浏览器        hot: true               // 开启热更新    }}

当然在npm run dev命令下,打包的文件存在于内存中,并不会产生在dist目录下

热更新和自动刷新的区别

在配置devServer的时候,如果hot为true,就代表开启了热更新

But这并没那么简单,因为热更新还需要配置一个webpack自带的插件并且还要在主要js文件里检查是否有module.hot

下面就让我们直接看下代码是如何实现的


// webpack.config.jslet webpack = require('webpack');
module.exports = {    plugins: [        // 热更新,热更新不是刷新        new webpack.HotModuleReplacementPlugin()    ],    devServer: {        contentBase: './dist',        hot: true,        port: 3000    }}
// 此时还没完虽然配置了插件和开启了热更新,但实际上并不会生效
// index.jslet a = 'hello world';document.body.innerHTML = a;console.log('这是webpack打包的入口文件');
// 还需要在主要的js文件里写入下面这段代码if (module.hot) {    // 实现热更新    module.hot.accept();}

以上index.js中的内容,如果将变量a的值进行修改保存后,会在不刷新页面的情况下直接修改掉,这样就实现了热更新。

那么热更新从现在看来和自动刷新浏览器的区别也不是太大嘛!自动刷新也是可以接受的啊。

其实不然,热更新的好处可能在vue或者react中有更大的发挥,其中某一个组件被修改的时候就会针对这个组件进行热更新了,这里用到vue或react的同学去实际体验一下吧。

resolve解析

在webpack的配置中,resolve我们常用来配置别名和省略后缀名


module.exports = {    resolve: {        // 别名        alias: {            $: './src/jquery.js'        },        // 省略后缀        extensions: ['.js', '.json', '.css']    },}

这个配置在webpack中比较简单,我们也就不再叙述了,下面来看点干货

提取公共代码

在webpack4之前,提取公共代码都是通过一个叫CommonsChunkPlugin的插件来办到的。到了4以后,内置了一个一模一样的功能,而且起了一个好听的名字叫“优化”

下面我们就来看看如何提取公共代码


// 假设a.js和b.js都同时引入了jquery.js和一个写好的utils.js// a.js和b.jsimport $ from 'jquery';import {sum} from 'utils';

那么他们两个js中其中公共部分的代码就是jquery和utils里的代码了

可以针对第三方插件和写好的公共文件


module.exports = {    entry: {        a: './src/a.js',        b: './src/b.js'    },    output: {        filename: '[name].js',        path: path.resolve('dust')    },    // 提取公共代码+   optimization: {        splitChunks: {            cacheGroups: {                vendor: {   // 抽离第三方插件                    test: /node_modules/,   // 指定是node_modules下的第三方包                    chunks: 'initial',                    name: 'vendor',  // 打包后的文件名,任意命名                        // 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包                    priority: 10                    },                utils: { // 抽离自己写的公共代码,utils这个名字可以随意起                    chunks: 'initial',                    name: 'utils',  // 任意命名                    minSize: 0    // 只要超出0字节就生成一个新包                }            }        }+   },    plugins: [        new HtmlWebpackPlugin({            filename: 'a.html',            template: './src/index.html',  // 以index.html为模板+           chunks: ['vendor', 'a']        }),        new HtmlWebpackPlugin({            filename: 'b.html',            template: './src/index.html',  // 以index.html为模板+           chunks: ['vendor', 'b']        })    ]}

通过以上配置,可以把引入到a.js和b.js中的这部分公共代码提取出来,如下图所示。

指定webpack配置文件

在package.json的脚步里,我们可以配置调用不同的webpack配置文件进行打包,举个栗子。

这样的好处在于可以针对不同的需求进行一个特定的打包配置。

就到这里吧

关于webpack4的一些常规操作就说到这里了,其实在工作当中更多时候,也并不需要我们去配置这些内容

不过我们要争做优秀的前端儿,所以就必须掌握这些必备的技能,必须会,没有之一!

好了,就写到这里吧,想必大家也看累了吧,辛苦大家了,哈哈。

这篇关于webpack4-用之初体验,一起敲它十一遍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/612160

相关文章

跟我一起玩《linux内核设计的艺术》第1章(四)——from setup.s to head.s,这回一定让main滚出来!(已解封)

看到书上1.3的大标题,以为马上就要见着main了,其实啊,还早着呢,光看setup.s和head.s的代码量就知道,跟bootsect.s没有可比性,真多……这确实需要包括我在内的大家多一些耐心,相信见着main后,大家的信心和干劲会上一个台阶,加油! 既然上篇已经玩转gdb,接下来的讲解肯定是边调试边分析书上的内容,纯理论讲解其实我并不在行。 setup.s: 目标:争取把setup.

Node.js初体验 Kali安装Node.js

背景:偶然看到node.js开发微信公众号的视频,有些好奇,想要接触下。然后花了两个小时在实验楼网站上在线学习了JavaScript的基础知识,以及Node.js的基础 接着本着从实践出发的原则 先去本地kali下安装个Node.js玩玩 下载地址:https://nodejs.org/en/download/ 网页最下面有提示:Note: Python 2.6 or 2.7 is requ

社交平台找旅游搭子一起旅行靠谱吗?答案是不要太爽!

哈喽小伙伴们,今天要跟大家分享一个超级棒的小程序——咕哇找搭子!作为一个热爱自由行的人,最头疼的就是找不到志同道合的小伙伴。但自从用了这个咕哇小程序后,一切都变得简单又充满乐趣啦!🎉 上个月,我计划去云南旅行,就试着在咕哇上发布了我的行程信息。没想到很快就收到了几位朋友的回应,其中一位叫小莲的朋友特别投缘。我们不仅目的地一样,就连兴趣爱好都出奇地相似,于是我们就决定一起出发啦!👭

python打包exe如何把浏览器和geckodriver一起打包进去

一、目录结构:main.py同级目录下有一个浏览器包 二、调用浏览器的py修改:根据开发环境和打包环境选择浏览器和webdriver的路径 if getattr(sys, 'frozen', False):# 如果是打包的应用程序application_path = sys._MEIPASSelse:# 如果是开发环境application_path = os.path.dirna

eclipse中设置中文字体变大,注释字体变大,不跟代码字体一起变大

windows-preferences-general-appearance-colours and fonts 在basic里面找到最后TEXT FONT,点edit,在右下角脚本里面将西欧语言改成中欧语言 解决

html初体验标准标签

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><input type="text"></body></html> 内容展示

跟我一起写 SIPp XML scenario file

编辑文件 uas.xml,内容为: <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE scenario SYSTEM "sipp.dtd"><scenario><recv request="INVITE"><action><ereg regexp="&lt;(sip:.*)&gt;" search_in="hdr" header="Contact

跟我一起学FPGA (二) 语法讲解

本章讲解 1 、Verilog 概述和基础知识; 2 、Verilog 程序框架和高级知识点; 3 、Verilog 编程规范。 1.Verilog 概述和基础知识 Verilog 是一种硬件描述语言,以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能. verilog的逻辑值:

微信公众号欢迎大家一起交流,一起分享

天涯何必曾相识,愿与诸君共奋进,2021年迎来了牛年,告别了2020年多灾多难的鼠年,祝福大家,在牛年里,小试牛刀,年气冲天。     欢迎大家,微信扫描,加入一起讨论分享。

【 OpenHarmony 4.1 Launcher 源码解析 】-- 初体验

前言 最近因为业务需要,需要做一款 UI 定制的鸿蒙 Launcher,于是就开始了「找到代码」、「研究代码」、「魔改代码」的套路流程,仅以此文章作为知识备份和技术探讨所用,也希望能给其他小伙伴提供一些源码的解析思路,方法大家各自魔改! 一、官方简介 Gitee codes:应用子系统/Launcher Launcher 作为系统人机交互的首要入口,提供应用图标的显示、点击启动、卸载应