网站不用下载免费软件,怎样弄一个自己的网站,app开发公司联系方式,运城有做网站设计一文了解webpack入门核心知识#x1f3a8;序言#x1f4c5;一、webpack究竟是什么1、写在前面2、什么是模块打包工具#xff1f;#x1f4d0;二、如何用Webpack搭建环境1、安装node2、创建项目3、初始化项目4、安装webpack5、安装具体版本的webpack⚙️三、Webpack的配置文… 一文了解webpack入门核心知识序言一、webpack究竟是什么1、写在前面2、什么是模块打包工具二、如何用Webpack搭建环境1、安装node2、创建项目3、初始化项目4、安装webpack5、安装具体版本的webpack⚙️三、Webpack的配置文件1、默认配置文件2、用npm script来简化我们的打包代码3、浅谈webpack打包输出内容四、Loader1、引例阐述2、什么是Loader3、使用Loader打包静态资源图片篇1自定义命名图片2打包各种类型的图片文件3打包到image文件下4url-loader4、使用Loader打包静态资源样式篇1打包css文件2打包sass文件3兼容性问题5、增加配置项6、如何使用webpack打包字体文件五、使用plugins让打包更便携1、html-webpack-plugin2、clean-webpack-plugin️六、Entry和Output️七、SourceMap1、引例阐述2、sourceMap3、sourceMap常见配置八、使用WebpackDevServer提升开发效率1、--watch2、webpackDevServer1安装webpackDevServer2配置package.json文件3配置 webpack文件4配置端口号️九、Hot Module Replacement 热模块更新1、引例阐述2、热模块更新配置十、使用Babel处理ES6语法1、ES6语法转换为ES5语法2、Babel-polyfill十一、结束语彩蛋 One More Thing往期推荐番外篇序言
众所周知在前端工程化日趋复杂的今天模块化打包工具在我们的日常开发中起着越来越重要的作用而其中 webpack 已然是前端打包构建的不二选择。
说到 webpack 可能很多小伙伴会觉得既熟悉又陌生熟悉是因为在我们开发的每一个项目中都会使用到它。而陌生在于 webpack 有着复杂的配置和五花八门的功能而感到陌生。
因此我们有时候会被这复杂的配置先吓到从而被劝退学习。
然而在技术更新迭代这么快的一个大环境下 webpack 还是很值得我们去学习的。
在下面的这篇文章中将讲解 webpack 的核心概念。一起来学习吧~
一、webpack究竟是什么
1、写在前面
当我们要写一个网页时首先我们会先创建一个 index.html 文件之后在可能还会有一些 js 文件那么我们就会在 html 文件中引入这些 js 文件。
试想一下如果 js 文件很多然后我们一个个引入这样如果遇到报错了呢会不会就很难定位到是哪个文件错了这样就会使得开发效率非常低下了。
因此就有了 webpack 。 webpack 会将我们所写的代码进行一个翻译并将翻译完的内容进行一个模块化的打包使得项目变得工程化。
接下来我们就来讲解 webpack 究竟是什么以及怎么安装使用。
2、什么是模块打包工具
webpack 有时候会被误认为是一个 js 的翻译器但其实 webpack 称不上是一个 js 的翻译器。
因为它只认识 import 这样类似的语句而不认识其他的 js 高级语法。所以如果称它是一个 js 的翻译器实际上是我们高看了它。
查看官方的定义我们可以发现 webpack 是一个模块打包工具同时 webpack 也可以支持 commonjs 的模块打包规范。
然而随着时间的推移和技术的不断更新 webpack 不再是只会打包 js 的模块打包工具 webpack 现在还支持 css文件 、 jpg 、 png 等各种文件的打包。
二、如何用Webpack搭建环境
1、安装node
webpack 是基于 nodejs 开发的模块打包工具本质上是由 node 实现的。因此我们要先安装本机的 node 环境。这里附上官方网站的链接建议大家下载稳定版本
之后查询本机的 node 和 npm 版本查看是否安装成功。
node -v
npm -v2、创建项目
先创建一个项目假设命名为 webpack-demo 。之后在该项目下通过以下命令创建一个文件夹
mkdir webpack-demo3、初始化项目
进入 webpack-demo 文件初始化项目。命令行如下
cd webpack-demo
npm init 或 npm init -y //加-y表示默认自动配置项之后一路 Enter 回车即可。
大家可以看到项目结构以上操作就是在 webpack-demo 文件下创建了一个 package.json 文件之后我们把 package.json 文件的内进行改造。具体代码如下
{name: webpack-demo,version: 1.0.0,description: ,//将这个项目设置为私有private:true,//main: index.js, //去掉入口文件scripts: {test: echo \Error: no test specified\ exit 1},//写上作者名author: Monday,//保持项目私有license: ISC
}
4、安装webpack
第一种方式全局安装
npm install webpack webpack-cli -g第二种方式当前项目下安装
npm install webpack webpack-cli -D在这里的建议是选择第二种方式进行安装。那为什么呢是因为全局安装 webpack 有什么问题吗
事实上全局安装只会安装一个版本。
那么假如我们现在要跑两个项目并且这两个项目出现原先安装的 webpack 版本不一样安装低版本 webpack 的项目就有可能会导致在我们的本机中运行不起来。所以建议是使用第二种方式进行安装。 安装完成之后我们还要来查询当前使用的 webpack 版本号以确保我们是否已经安装成功。具体命令行如下
npx webpack -v这个时候就有小伙伴会有疑问说为什么前面还要加个 npx 才能查找版本号。
原因在于我们只在当前项目中安装所以 webpack 这个命令在全局中并没有找到。而 node 提供了 npx 这个时候 npx 就可以找到我们所运行项目目录下的 node-module 中的 webpack 安装包所以这种方式是把我们的 webpack 安装在我们的项目内然后通过 npx 去运行 webpack 就可以了。
5、安装具体版本的webpack
如果我们想要安装具体版本号的 webpack 那么我们先查看 webpack 的版本号信息。命令如下
npm info webpack查到具体版本号以后使用以下命令进行安装
npm install webpack4.16.5 webpack-cli -D //4.16.5表示版本号⚙️三、Webpack的配置文件
1、默认配置文件
很多时候我们还没写配置文件项目就成功跑起来了。这并不是因为不用写而是 webpack 团队提前帮我们写好了很多默认的配置文件使得我们在运行项目时不用进行过多的配置就可以达到我们的使用需求。那下面就跟着大家一起来写一个配置文件。
我们先来了解下项目结构在我们创建完项目时我们的源代码一般放在 src 文件夹下并且打包后的文件一般放在 dist 文件下同时 webpack 的配置文件命名为 webpack.config.js 并且放在项目的根目录下。
├── dist 放置打包后的文件
├── src 放置项目源代码
├── webpack.config.js webpack配置文件
├── package-lock.json
├── package.json看完项目结构我们来了解一下 webpack 的配置文件具体需要怎么配置。具体代码如下
//node的核心模块
const path require(path);module.exports {//设置为development时代码不会进行压缩设置为production时代码会进行压缩。mode:production,// 放置入口文件明确怎么打包要打包哪一个文件entry: ./src/index.js,//entry: {// main: ./src/index.js//},// 输出表明webpack应该怎么输出输出到哪个地方output: {filename: bundle.js,// 指打包后的文件要放在哪个文件下// __dirname表示该项目的根目录path: path.resolve(__dirname, dist)}
}了解完基本配置此时可能有小伙伴心里有一个疑惑 webpack 配置文件的命名一定要命名为 webpack.config.js 吗是否可以命名为其他的呢
答案是肯定可以的不过我们需要进行一个特殊处理。平常如果我们命名为 webpack.config.js 时可以直接使用 npm webpack 来跑我们的项目。如果不用这个命名时假设命名为 webpackconfig.js 那么我们可以通过以下命令行来打包我们具体的项目。 npx webpack --config webpackconfig.js 以上命令行的意思为指让 webpack 来帮我们打包具体打包哪一个文件呢以 webpackconfig.js 为配置文件来帮我们打包。
2、用npm script来简化我们的打包代码
看完上面的内容相信小伙伴们对 webpack 有了一个基础的认识。
那试想以下经常要使用 npx webpack 来帮我们打包文件这样是不是会有点略显麻烦呢
所以我们来再了解一个内容使用 npm script 来简化我们的打包代码。
再我们的项目根目录下会有一个 package.json 文件这个文件的代码如下
{name: webpack-demo,version: 1.0.0,description: ,private: true,main: index.js,scripts: {test: echo \Error: no test specified\ exit 1},author: Monday,license: ISC,devDependencies: {webpack: ^5.39.1,webpack-cli: ^4.7.2}
}
大家定位到scripts部分接下来我们把script部分进行一个改造。具体代码如下 scripts: {/* webpack 会先到node_module下面进行打包*/bundle: webpack},改造完成以后我们就相当于在 package.json 里面配置了一个 npm script 上面的代码意思为这个 script 对应的名字叫做 bundle 之后呢 bundle 的底层会帮助我们执行 webpack 并进行打包。
这么编写之后我们就不再需要使用 npx webpack 来做运行 webpack 而是使用 npm run bundle 来做命令进行打包。
3、浅谈webpack打包输出内容
讲解完上面的内容我们来对 webpack 打包以后控制台的一些输出内容进行归纳总结。
输出内容具体含义hash代表本次打包对应的唯一哈希值version代表此次打包使用的webpack的版本time当前项目整体打包的具体耗时assets打包后的文件具体是哪一个比如bundle.jssize打包后文件的大小chunks放置自己对应文件的id值以及对应文件所引入其他文件的id值chunk Names对应entry配置的main
四、Loader
1、引例阐述
Webpack 默认是知道如何打包 js 模块的但是它不知道 jpg 这种文件该怎么打包。
这个时候我们需要在 webpack.config.js 文件下做配置配置 file-loader 。我们在配置中增加一个新的 module 。具体代码如下
module:{rules:[{test:/\.jpg$/,use:{loader:file-loader}}]},接下来我们来正向分析下 webpack 是如何打包 jpg 这种静态文件的。
首先 webpack 会进入src 目录 new 一个 index.js 文件那么现在我们要对这个文件进行打包。
所以我在命令行里运行了 npm run bundle 。当你运行 npm run bundle 时实际上在执行的是 package.json 里面的 script 这个 script 帮我们运行 webpack 然后呢 webpack 帮我们做打包。这个时候 webpack 就会去找它相对应的配置根据这个配置帮我们做打包。
那么我们来看一下如果我们遇到的是 js 文件那么 webpack 默认会进行打包。但是呢如果遇到的是一张 jpg 的图片呢 webpack 这个时候就懵了 webpack 并不认识 jpg 这种格式的代码。
因此我们就可以引用一个模块module来帮我们打包。这个模块叫 file-loader file-loader 这个 loader 就可以帮助我们完成打包的过程。
那么实际上 file-loader 的底层帮我们做了什么事情呢
当我们打包 jpg 文件时 webpack 会把 jpg 文件移动到 dist 文件下并且对 jpg 文件赋予一个新的名称。然后呢它会把这个名称作为一个返回值返回给我们引入模块的变量之中。
这就是 file-loader 底层处理打包文件的一个流程。
当然。 file-loader 不仅仅可以处理 jpg 这样的文件图片。理论上它还可以处理很多种类型的静态资源。
2、什么是Loader
阐述了 file-loader 之后相信大家对 loader 有了一个基础认识。那么我们现在就来对loader的基础定义进行梳理。具体如下
本身 webpack 对于一些文件是不知道如何处理的但是 loader 知道。所以呢当遇到一些 非js 文件时一般去求助于 loader 就可以了。因此我们就需要让 webpack 去求助 loader 模块来识别出 非js 的文件。
引用 webpack 官方中文文档的一句话文档中说到 webpack 只能理解 JavaScript 和 JSON 文件这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件并将它们转换为有效模块以供应用程序使用以及被添加到依赖图中。本质上 loader 是导出为函数的 JavaScript 模块。
3、使用Loader打包静态资源图片篇
1自定义命名图片
如果我们现在要对打包后的图片进行自定义命名那该怎么做呢
我们在 webpack.config.js 文件下的 module 再进行改进。具体代码如下
module:{rules:[{test:/\.jpg$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext]}}}]
}通过配置 options 就可以达到图片自定义命名的效果。
2打包各种类型的图片文件
假设我们现在不局限于打包 jpg 文件还想要打包其他的图片文件。那么我们可以这样配置
module:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext]}}}]
}通过正则表达式的方式来增加新的图片类型。
3打包到image文件下
假设我们现在想要把打包后的文件放到 image 文件下那该怎么做呢具体代码如下
module:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext],//将jpg、png和gif图片文件指定到dist目录下的images文件下outputPath: images/}}}]
}4url-loader
在使用了 file-loader 之后我们再来了解一个知识点 url-loader 。 url-loader 可以达到几近 file-loader 的效果。具体使用方法如下
npm i url-loader -Dmodule:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:url-loader,options: {name: [name]_[hash].[ext],outputPath: images/}}}]
}我们只要安装上 url-loader 并且在配置中将 file-loader 替换为 url-loader 即可。
但值得注意的是使用 url-loader 进行打包会有一些需要注意的事项。
当你去打包一个 jpg 文件的时候与 file-loader 不一样的是 url-loader 会将图片转换成一个 base64 的字符串然后直接放到我们 dist 目录下的 bundle.js 里面而不是单独生成一个图片文件。
好处就是直接访问而不用去文件夹下访问节省了一次 http 请求。
而带来的坏处就是如果这个 js 文件特别大那么打包生成的js文件也将会特别大随之加载这个 js 的时间就会很长。
所以 url-loader 的最佳使用方式是什么呢
如果说我们引入的图片很小只有 1~2KB 等小的体积那么这个图片以 base64 的形式打包到 js 文件里是一个很好的选择就没有必要让这么小的图片再去发一次 http 请求。
但假设这个图片很大的话那么尽量不要使用 url-loader 而使用 file-loader 把这个图片打包到dist目录下不要打包到 bundle.js 里面。不然会使得 bundle.js 文件变得很大使得加载时间变得很长不利于维护。
还有一种方法就是我们可以直接在 url-loader 下再加一个配置 limit 。具体代码如下
module:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:url-loader,options: {name: [name]_[hash].[ext],outputPath: images/,//2048020KBlimit: 20480}}}]
}通过以上代码我们可以知道当使用 url-loader 时我们可以给其加一个 limit 属性。那么上面代码所要表达的意思就是当图片文件大小大于 20KB 时我们使用 url-loader 打包。当大于 20KB 时就将图片文件放到 dist 的 images 文件下。
4、使用Loader打包静态资源样式篇
1打包css文件
比如说我们现在想要让一张图片的大小为 150*150 那么我们就需要写下样式来修改这张图片。那 webpack 如何打包 css 文件呢
我们可以使用 css-loader 和 style-loader 来对文件进行打包。具体配置如下
npm install sass-loader node-sass --save-devmodule:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext],outputPath: images/}}},{test:/\.css$/,use:[style-loader, css-loader]}]
}css-loader 会帮我们分析出几个 css 文件之间的关系最终把一个 css 文件合并成一个 css 。那 style-loader 的作用又是是什么呢
在得到了 css-loader 生成的 css 文件之后 style-loader 会把这段内容挂载到页面的 head 部分并将样式挂载到 head 中的 style/style 里面。
2打包sass文件
如果是要打包 sass 文件呢则使用 sass-loader 、 style-loader 和 css-loader 这三个 loader 来对文件进行打包。具体配置如下
npm install sass-loader node-sass --save-devmodule:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext],outputPath: images/}}},{test:/\.scss$/,use:[style-loader, css-loader, sass-loader]}]
}值得注意的是 loader 的执行顺序是从下到上从右到左。
所以当我们去执行一个 sass 文件时首先会执行 sass-loader 之后执行 css-loader 最后才执行 style-loader 。
3兼容性问题
有时候我们如果想要兼容多个浏览器时那么我们可能会在 css 文件里面添加 -webkit- 等厂商的前缀。但是呢要知道 webpack 是没办法识别这些前缀的。这个时候我们了解一个新的 loader 就是 postcss-loader 这个loader可以自动地帮我们添加厂商前缀的信息。具体使用方式如下
首先我们先安装 postcss-loader 这个库具体代码如下
npm i postcss-loader -D安装完成之后我们在项目根目录下创建一个新的文件名字叫 postcss.config.js 之后对这个文件进行配置代码如下
首先安装 autoprefixer
npm install autoprefixer -D安装完成之后现在我们在 postcss.config.js 文件下来使用它具体代码如下
module.exports {Plugin:[require(autoprefixer)]
}接下来我们在 webpack.config.js 文件下面使用 postcss-loader 。具体代码如下
module:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext],outputPath: images/}}},{test:/\.scss$/,use:[style-loader, css-loader, sass-loader,postcss-loader]}]
}通过以上方式 webpack 就可以在帮我们打包静态文件时把对应的需要加入厂商前缀的样式给添加上前缀。
5、增加配置项
假设我们现在想要给某一个 loader 增加配置项比如说我们要给 css-loader 增加配置项那么我们可以对代码进行如下处理。具体代码如下
module:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext],outputPath: images/}}},{test:/\.scss$/,use:[style-loader, {loader: css-loader,options: {//表明前面要先走sass-loader和postcss-loaderimportLoaders: 2}}, sass-loader,postcss-loader]}]
}从以上代码中我们可以看到当我们想要给 css-loader 增加配置项时那么不再使用字符串的形式我们把字符串转化成一个对象。在对象里面我们填写相应的 loader 和 options 配置这样就达到了我们想要的需求。 有时候我们在一个页面上如果全局引入 css 可能会很容易导致样式冲突问题。那这种情况该怎么处理呢
为此我们可以借助 css-loader 中的 modules 来实现 css 的模块化旨在让引入的 css 文件拥有它独立的模块。那具体该怎么使用呢
module:{test:/\.scss$/,use:[style-loader, {loader: css-loader,options: {//表明前面要先走sass-loader和postcss-loaderimportLoaders: 2,modules: true}},sass-loader,postcss-loader]}]
}从以上代码中我们可以知道通过 modules:true 语句就可以开启 css 的模块化打包。开启之后我们就可以在各种文件下引入。引入方式如下
import style from ./index.scss;var img new Image();
img.src bug;
img.classList.add(style.bug);从上述代码中我们可以看到开启 module 后就可以随心所欲的引用该 css 中的内容啦
6、如何使用webpack打包字体文件
有时候我们在项目中有可能会遇到想要引入字体的问题那 webpack 如何打包字体呢具体代码如下
module:{rules:[{test: /\.(eot|ttf|svg)$/,use: {loader: file-loader,}}]},通过以上代码我们可以知道跟 webpack 相关的静态文件格式为 eot、ttf和svg 等格式所以需要需要把这几种类型引入。同时跟其相关的 loader 为 file-loader 。
学完关于如何打包静态资源后建议可以再用官方文档的相关部分来进行复习具体链接戳~
五、使用plugins让打包更便携
1、html-webpack-plugin
在学习了如何使用 loader 来打包静态文件之后接下来我们一起来了解在 webpack 中如何使用 plugins 让打包更便捷。
我们在打包项目时 webpack 总是会把打包后的内容放到 dist 目录下。这个时候我们可能还需要自行再去创建一个 index.html 来引入核心文件。那这样会不会就显得略有点麻烦了
因此 webpack 给我们提供了 plugin 插件来解决这个问题。
首先我们先来安装 plugin 具体命令行如下
npm install html-webpack-plugin -D接下来我们将插件引入 webpack.config.js 当中具体代码如下
const HtmlWebpackPlugin require(html-webpack-plugin);plugins: [new HtmlWebpackPlugin({//表明要引用哪一个模板template: src/index.html})]现在我们来梳理一下 htmlWebpackPlugin 如何帮我们完成自动打包。
首先 htmlWebpackPlugin 会在打包结束后自动生成一个 html 文件。之后呢把打包生成的 js 文件自动引入到这个 html 文件中。
所以从某种程度上来说就是 plugin 可以在 webpack 运行到某个时刻的时候自动地帮你做一些事情。即当我们打包结束的这儿一时刻 plugin 会自动帮我们创建 html 文件以供我们直接使用。
2、clean-webpack-plugin
有时候我们有可能对 webpack.config.js 中的output所对应的filename进行修改这就很容易导致在打包过程中遇到多文件冲突。
那么我们想要实现的就是在打包时先清空原来的dist文件夹然后再生成一个新的dist文件夹。如何处理呢请看下方。
首先我们先安装依赖 clean-webpack-plugin 具体命令行如下
npm install clean-webpack-plugin -D接下来我们将插件引入 webpack.config.js 当中具体代码如下
const CleanWebpackPlugin require(clean-webpack-plugin);plugins: [new HtmlWebpackPlugin({//表明要引用哪一个模板template: src/index.html}),new CleanWebpackPlugin([dist])]通过以上代码就可以在我们项目打包时先删除 dist 文件夹之后再创建一个新的文件夹。
️六、Entry和Output
接下来我们再来看 webpack 中的 entry 和 output 中几个比较核心的配置。
module.exports {mode:development,// 放置入口文件明确怎么打包entry:{main: ./src/index.js,sub: ./src/index.js},plugins: [new HtmlWebpackPlugin({//表明要引用哪一个模板template: src/index.html}),new CleanWebpackPlugin([dist])],// 输出表明webpack应该怎么输出output: {//如果把资源放在cdn下则引入cdnpublicPath: http://cdn.com.cn,//当entry有多个入口文件时用[]可以输出多个文件filename: [name].js,// 指打包后的文件要放在哪个文件下path: path.resolve(__dirname, dist)}
}️七、SourceMap
1、引例阐述
有时候我们在写代码时总会莫名的出bug。看着控制台那红红的报错心里总归很不是滋味。同时如果我们没有配置好 webpack 的话那错误找起来简直是很恐怖的。
比如在开发模式下我们默认 webpack.config.js 像下面这样配置具体代码如下
module.exports {mode:development,devtool: none,entry:{//打包到dist目录下的main.jsmain: ./src/index.js},output: {//用[]可以生成多个文件filename: [name].js,// 指打包后的文件要放在哪个文件下path: path.resolve(__dirname, dist)}
}然后呢假设我们现在代码里面错把 console.log 写成 consele.log 。那么现在控制台的打印效果如下 大家可以看到此时的错误定位到打包后的 main.js 文件里面的第96行。那试想一下如果我们的业务代码特别多报错有可能就是在文件中的上前行了。
这样的场景并不是我们想看到的。我们想做的事情呢就是希望 webpack 打包完成之后就把错误直接抛给我们并把其对应的具体文件地址显示出来。也就是我们出错的那个代码文件而不是打包后的文件 main.js 。
因此 webpack 给我们提供了 sourceMap 这个配置来解决这个问题。
2、sourceMap
我们现在把 devtool 这个配置改成 sourceMap 。具体代码如下
module.exports {mode:development,devtool: source-map,entry:{//打包到dist目录下的main.jsmain: ./src/index.js},output: {//用[]可以生成多个文件filename: [name].js,// 指打包后的文件要放在哪个文件下path: path.resolve(__dirname, dist)}
}改完之后呢我们来看一下控制台的打印结果 现在大家可以看到改成 source-map 的配置之后报错的定位直接到了我们自己所编写代码的目录下即 index.js 。而不再是大海捞针似的在 main.js 里面找。
3、sourceMap常见配置
看完上面的例子之后相信大家对 SourceMap 有了一定的了解。接下来我们来看一下 sourceMap 的一些常见配置。具体看看下方
SourceMap含义inline-source-map报错时将行和列都显示出来cheap-inline-source-map报错时只知道哪一行出错了不知道在哪一列cheap-module-source-map生产环境最佳实践不仅管自己的业务代码错误还要管其他的其他的错误像loader、其他第三方模块的错误等等evaleval是打包速度最快的一种方式但如果遇到业务代码比较复杂的情况下用eval提示出来的效果可能不太全面module-eval-source-map用module表明不仅要显示业务错误还要显示loader、第三方错误等等cheap-module-eval-source-map开发环境最佳实践
八、使用WebpackDevServer提升开发效率
1、–watch
事实上如果我们不采用 WebpackDevServer 的方式来开发的话那么我们每一次想要查看编译后的运行结果都需要先命令行编译 npm run bundle 命令之后再打开 dist 目录下的 index.html 文件才能重新查看。这样一来二往的难免效率低下。我们期待的结果是什么呢
我们把 package.json 文件里的 script 进行一番改造具体代码如下
scripts: {watch: webpack --watch,bundle: webpack},通过以上代码大家可以看到将 webpack 后面加上 --watch 字段然后运行 npm run watch 就可以每次修改完代码后 webpack 实现自动监听而不用像以往那样每修改一次代码都要对再重新运行命令来对 webpack 进行打包。
2、webpackDevServer
但是呢这种方式可能还不够友好毕竟开发者总是懒惰的能尽量让程序来干活就不要用手工来干活。
实际上我们想要达到的效果是当我们运行完 npm run watch 这行命令的时候不仅能自动帮我们实现打包同时还能帮我们打开控制台并且模拟一些服务器上的特性。那么我们就可以通过 webpackDevServer 来实现我们想要的效果。如何使用 webpckDevServer 呢具体看下方。
1安装webpackDevServer
我们现在项目中安装webpackDevServer具体命令行如下
npm install webpack-dev-server -D2配置package.json文件
接下来我们来配置 package.json 文件的 script 。具体代码如下
scripts: {watch: webpack --watch,start: webpack-dev-server},3配置 webpack文件
接下面我们来配置 webpack.config.js 文件具体代码如下
module.exports {mode:development,devtool: source-map,// 放置入口文件明确怎么打包entry:{main: ./src/index.js},devServer: {contentBase: ./dist,// 当运行完npm run start时会自动的帮我们打开浏览器open: true},output: {//用[]可以生成多个文件filename: [name].js,// 指打包后的文件要放在哪个文件下path: path.resolve(__dirname, dist)}
}那么现在我们来看下 webpackDevServer 如何做到自动打开浏览器。详情见下图 大家可以看到通过 webpackDevServer 它不但会监听到我们的文件发生了改变重新帮我们进行打包。同时它还会自动的帮我们重新刷新浏览器并且会自动地帮我们打开浏览器。所以用它呢可以大大提升我们的代码开发效率。
4配置端口号
webpackDevServer 默认我们服务器的端口号是 8080 如果我们想要修改它为其他的端口号该怎么做呢
我们需要在来修改 webpack.config.js 文件下的 DevServer 具体代码如下
module.exports {mode:development,devtool: source-map,// 放置入口文件明确怎么打包entry:{main: ./src/index.js},devServer: {contentBase: ./dist,// 当运行完npm run start时会自动的帮我们打开浏览器open: true,//修改端口号port: 3000},output: {//用[]可以生成多个文件filename: [name].js,// 指打包后的文件要放在哪个文件下path: path.resolve(__dirname, dist)}
}我们只需要在 devServer 里面加上一个 port 的配置即可实现自定义端口号。
同时值得注意的是当我们在用 webpackDevServer 帮我们项目做打包时它不会自动生成 dist 目录那这是为什么呢用 webpackDevServer 打包后的项目会放在我们的电脑内存中这在某种程度下可以有效的提升项目的打包速度让打包变得更快。
️九、Hot Module Replacement 热模块更新
1、引例阐述
假设我们现在要实现一个新增元素的功能这个功能所要达到的效果是每点击一次按钮就新添加一次文本 item 。具体实现代码如下
index.js文件
import ./style.css;var btn document.createElement(button);
btn.innerHTML 新增;
document.body.appendChild(btn);btn.onclick function(){var div document.createElement(div);div.innerHTML item;document.body.appendChild(div);
}style.css文件
div:nth-of-type(odd){background: yellow;
}此时浏览器的显示效果如下图所示 假设我们现在来给css的背景改个颜色比如说改成紫色。具体代码如下
div:nth-of-type(odd){background: purple;
}此时我们保存后浏览器会重新进行刷新之后每一个 item 又要重新 append 进来。如下图 那这种情况下可能就不是我们想要的结果了。我们希望的是所有的 item 不进行重新刷新并且当 css 样式改变的时候对应的 item 颜色也可以得到改变。那么这就要引出 webpackDevServer 中的一个内容热模块更新 Hot Module Replacement 。接下来我们来了解热模块更新相关的配置。
2、热模块更新配置
热模块更新即Hot Module Replacement简称为 HMR 。
接下来我们在 webpack.config.js 文件夹下进行配置。具体代码如下
//node的核心模块
const path require(path);
const HtmlWebpackPlugin require(html-webpack-plugin);
const CleanWebpackPlugin require(clean-webpack-plugin);
const webpack require(webpack);module.exports {mode:development,devtool: source-map,// 放置入口文件明确怎么打包entry:{main: ./src/index.js},devServer: {contentBase: ./dist,// 当运行完npm run start时会自动的帮我们打开浏览器open: true,port: 8080,// 让我们的webpackDevServer开启hotModuleReplacement这样子的功能hot: true,// 即便HMR没有生效也不让浏览器自动刷新hotOnly: true},module:{rules:[{test:/\.(jpg|png|gif)$/,use:{loader:file-loader,options: {//placeholder 占位符name: [name]_[hash].[ext],outputPath: images/,limit: 10240}}},{test:/\.scss$/,use:[style-loader, {loader: css-loader,options: {//表明前面要先走sass-loader和postcss-loaderimportLoaders: 2,modules: true}}, sass-loader,postcss-loader]},{test:/\.css$/,use:[style-loader,css-loader,postcss-loader]}]},plugins: [new HtmlWebpackPlugin({//表明要引用哪一个模板template: src/index.html}),new CleanWebpackPlugin([dist]),new webpack.HotModuleReplacementPlugin()],// 输出表明webpack应该怎么输出output: {// 下载middlenpm install express webpack-dev-middleware -DpublicPath: /,//用[]可以生成多个文件filename: [name].js,// 指打包后的文件要放在哪个文件下path: path.resolve(__dirname, dist)}
}通过以上代码我们可以知道配置 devServer 下的 hot 和 hotOnly 以及 plugins 下的 new webpack.HotModuleReplacementPlugin() 来达到热模块更新的效果。
接下来我们来看一下进行配置之后浏览器的效果。详情见下图 大家可以看到加上这几个配置之后 item 不会再重新刷新了而是在原来的基础上进行样式修改。
十、使用Babel处理ES6语法
1、ES6语法转换为ES5语法
继续接下来我们来了解如何使用webpack和babel来编写ES6的语法。
大家都知道ES6的语法规范是2015年才正式出版的。所以有时候并不是所有的浏览器都支持ES6语法。因此我们现在想要做的事情就是在webpack打包时能够将ES6的语法转换为ES5的语法。这样项目运行的时候浏览器就不会报错了。
那怎么实现这样子的打包呢接下来我们一起来了解一下。
首先我们打开babel的官方网站按照步骤我们一步步在 webpack 中使用 babel 。
第一步 安装 babel-loader 和 babel/core 这两个库。具体代码如下
npm install --save-dev babel-loader babel/corebabel-loader 是帮助webpack进行打包使用的一个工具而 babel/core 则是 babel 的一个核心库它能够让 babel 去识别 js 代码里的内容然后呢把 js 代码转换成 AST 抽象语法树之后再把抽象语法树编译成一些新的语法。
第二步 在 webpack.config.js 文件下的配置项里增设规则。具体代码如下
module: {rules: [{test: /\.m?js$/,exclude: /node_modules/,use: {loader: babel-loader,options: {presets: [babel/preset-env]}}}]
}第三步 安装 babel/preset-env 。具体代码如下
npm install babel/preset-env --save-dev为什么要安装这个模块呢实际上当我们使用 babel-loader 处理文件时实际上 babel-loader 只是 webpack 和 babel 之间做通信的一个桥梁它只是帮我们打开了一个通道但是它并不会帮我们把 ES6 的语法转换为 ES5 的语法。所以我们就还需要借助一些其他的模块来做这项工作。这个模块就是前面我们说的preset-env 。
babel/preset-env 包含了所有 ES6 转换为 ES5 的语法规则当使用此模块打包时就可以把我们所有 js 中 ES6 的代码转换为 ES5 了。具体配置方式见以上第二步。
2、Babel-polyfill
通过以上的方式我们可以达到将ES6语法转换为ES5语法的效果。但是呢我们还要考虑到的一个问题就是如果遇到像promise这一类新的语法变量或者时像数组里面map这一类的函数低版本的浏览器里面实际上还是不存在的。虽然我们做了语法解释和语法翻译但也只是翻译了一部分。还有一些对象和函数在低版本的浏览器还是没有的。
所以呢这个时候我们不仅要使用 babel/preset-env 做语法转换还要把这些缺失的变量和函数补充到低版本的浏览器里面。
那怎么补充呢这个时候我们就需要借助 babel-polyfill 这个工具来进行补充。接下来讲解这个模块的使用操作。
第一步 定位到官方文档安装 babel-polyfill 。具体代码如下
npm install --save babel/polyfill第二步 引入该模块。具体代码如下
import babel/polyfill;通常情况下这段代码放到项目的 js 入口文件下。
第三步 改造 webpack.cofig.js 文件下的 module 减少打包大小。具体代码如下
module: {rules: [{test: /\.m?js$/,exclude: /node_modules/,use: {loader: babel-loader,options: {presets: [[babel/preset-env],{useBuiltIns: usage}]}}}]
}这段代码的意思就是当用 babel-polyfill 填充低版本浏览器特性的时候不是把是多有的特性都加进来而是根据我们的业务代码来决定到底到加什么。
同时 babel-preset 也有很多其他值得学习的配置属性这里不再进行讲解。大家可以自行到官方文档上进行查看~
十一、结束语
写完这篇文章的时候突然想起上次面试时的面试官。在最后的反问环节问他关于 webpack 的问题他说 webpack 一般会让对公司业务很熟悉的员工来处理毕竟前端工程化不是儿戏。
当时我还没有很大的感触但现在学到这里突然就想到了那个场景。确实是这样我这才学了不到它的冰山一角就已经感到 webpack 的庞大工程了。如果在打包时候但凡有一个小地方的配置出现问题就有可能引发整个项目的不可收拾局面。当然一般情况下不会出现这样的情况言重了……
在学习 webpack 的过程中要明确好自己所使用的webpack版本。比如周一刚开始迷迷糊糊的感觉版本4和版本5都差不多。但对于 webpack 来说这完全就是在跟它开玩笑。每一个依赖都有4和5对应的版本而不是说想用哪个就哪个。如果胡乱使用的话无形之中可能会报错到怀疑人生……
因此确定好此时用 webpack 打包时所使用的版本并在使用 npm 依赖时也同样要找到对应的版本来进行使用降低错误的发生。
到这里关于webpack的超入门知识就讲到这里啦希望对大家有帮助~
本文代码已上传至公众号后台回复关键词 webpack 即可获取~
彩蛋 One More Thing
往期推荐
vuejs基础知识系列vuejs原理分析系列
番外篇 关注公众号星期一研究室第一时间关注学习干货更多精选专栏待你解锁~ 如果这篇文章对你有用记得留个脚印再走哦~ 以上就是本文的全部内容我们下期见