万字总结webpack的超入门核心知识(二)

简介: 在下面的这篇文章中,将讲解 webpack 的入门核心概念。一起来学习吧~🎬

🧲五、使用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 中的 entryoutput 中几个比较核心的配置。

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下,则引入cdn
    publicPath: '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.js
    main: './src/index.js'
  },
    output: {
    //用[]可以生成多个文件
    filename: '[name].js',
    // 指打包后的文件要放在哪个文件下
    path: path.resolve(__dirname, 'dist')
  }
}
复制代码

然后呢,假设我们现在代码里面错把 console.log 写成  consele.log 。那么现在控制台的打印效果如下:

46.png

大家可以看到,此时的错误定位到打包后的 main.js 文件里面的第96行。那试想一下,如果我们的业务代码特别多,报错有可能就是在文件中的上前行了。

这样的场景并不是我们想看到的。我们想做的事情呢就是,希望 webpack 打包完成之后就把错误直接抛给我们,并把其对应的具体文件地址显示出来。也就是我们出错的那个代码文件,而不是打包后的文件 main.js

因此, webpack 给我们提供了 sourceMap 这个配置,来解决这个问题。


2、sourceMap

我们现在把 devtool 这个配置,改成 sourceMap具体代码如下:

module.exports = {
  mode:'development',
  devtool: 'source-map',
    entry:{
        //打包到dist目录下的main.js
    main: './src/index.js'
  },
    output: {
    //用[]可以生成多个文件
    filename: '[name].js',
    // 指打包后的文件要放在哪个文件下
    path: path.resolve(__dirname, 'dist')
  }
}
复制代码

改完之后呢,我们来看一下控制台的打印结果:

47.png

现在大家可以看到,改成 source-map 的配置之后,报错的定位直接到了我们自己所编写代码的目录下,即 index.js 。而不再是大海捞针似的在 main.js 里面找。


3、sourceMap常见配置

看完上面的例子之后,相信大家对 SourceMap 有了一定的了解。接下来我们来看一下 sourceMap 的一些常见配置。具体看看下方:

SourceMap 含义
inline-source-map 报错时将行和列都显示出来
cheap-inline-source-map 报错时只知道哪一行出错了,不知道在哪一列
cheap-module-source-map 生产环境最佳实践,不仅管自己的业务代码错误,还要管其他的其他的错误,像loader、其他第三方模块的错误等等
eval eval是打包速度最快的一种方式,但如果遇到业务代码比较复杂的情况下,用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 -D
复制代码


(2)配置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 如何做到自动打开浏览器。详情见下图:

1.png

大家可以看到,通过 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;
}
复制代码

此时浏览器的显示效果如下图所示:

2.png


假设我们现在来给css的背景改个颜色,比如说改成紫色。具体代码如下:

div:nth-of-type(odd){
    background: purple;
}
复制代码

此时我们保存后浏览器会重新进行刷新,之后每一个 item 又要重新 append 进来。如下图:

3.png

那这种情况下可能就不是我们想要的结果了。我们希望的是,所有的 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-loader
            importLoaders: 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: {
    // 下载middle:npm install express webpack-dev-middleware -D
    publicPath: '/',
    //用[]可以生成多个文件
    filename: '[name].js',
    // 指打包后的文件要放在哪个文件下
    path: path.resolve(__dirname, 'dist')
  }
}
复制代码

通过以上代码我们可以知道,配置 devServer 下的 hothotOnly ,以及 plugins 下的 new webpack.HotModuleReplacementPlugin() ,来达到热模块更新的效果。

接下来我们来看一下,进行配置之后,浏览器的效果。详情见下图:

4.png

大家可以看到,加上这几个配置之后, 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/core
复制代码

babel-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 只是 webpackbabel 之间做通信的一个桥梁,它只是帮我们打开了一个通道,但是它并不会帮我们把 ES6 的语法转换为 ES5 的语法。所以,我们就还需要借助一些其他的模块,来做这项工作。这个模块就是前面我们说的,preset-env

babel/preset-env ,包含了所有 ES6 转换为 ES5 的语法规则,当使用此模块打包时,就可以把我们所有 jsES6 的代码转换为 ES5 了。具体配置方式见以上第二步


2、Babel-polyfill

通过以上的方式,我们可以达到将ES6语法转换为ES5语法的效果。但是呢,我们还要考虑到的一个问题就是,如果遇到像promise这一类新的语法变量,或者时像数组里面map这一类的函数,低版本的浏览器里面,实际上还是不存在的。虽然我们做了语法解释和语法翻译,但也只是翻译了一部分。还有一些对象和函数,在低版本的浏览器还是没有的。

所以呢,这个时候我们不仅要使用 babel/preset-env 做语法转换,还要把这些缺失的变量和函数补充到低版本的浏览器里面

那怎么补充呢,这个时候我们就需要借助 babel-polyfill 这个工具来进行补充。 babel-polyfill 旨在用于实现浏览器并不支持的原生API的代码。接下来讲解这个模块的使用操作。

第一步: 定位到官方文档,安装 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的超入门知识就讲到这里啦!希望对大家有帮助~


相关文章
|
6月前
|
JSON JavaScript 前端开发
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(下)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
89 2
|
JSON 前端开发 JavaScript
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(一)
前端AJAX入门到实战,学习前端框架前必会的(ajax+node.js+webpack+git)(一)
589 0
|
2月前
|
JSON 前端开发 JavaScript
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
该文章提供了Webpack的基础入门指南,涵盖安装配置、基本使用、加载器(Loaders)、插件(Plugins)的应用,以及如何通过Webpack优化前端项目的打包构建流程。
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
|
2月前
|
缓存 JSON 前端开发
webpack入门核心知识还看不过瘾?速来围观万字入门进阶知识
该文章深入探讨了Webpack的高级配置与使用技巧,包括Tree Shaking、开发与生产环境的配置差异、代码分割策略、预加载与预取技术的应用等方面的内容。
|
6月前
|
Web App开发 JSON 前端开发
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
236 0
|
6月前
|
存储 前端开发 JavaScript
Webpack【Webpack中模式(Mode)、Webpack中使用DevServer、Webpack中devtool增强调试过程】(二)-全面详解(学习总结---从入门到深化)
Webpack【Webpack中模式(Mode)、Webpack中使用DevServer、Webpack中devtool增强调试过程】(二)-全面详解(学习总结---从入门到深化)
165 0
|
6月前
|
JSON 前端开发 JavaScript
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)(上)
Webpack【搭建Webpack环境、Webpack增加配置文件、Webpack中使用Loader、Webpack分离CSS文件 】(一)-全面详解(学习总结---从入门到深化)
90 0
|
6月前
|
JSON 前端开发 JavaScript
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
75 0
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
|
6月前
|
前端开发 JavaScript
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)(上)
Webpack【Webpack图片处理、Webpack中proxy代理 、自动清理dist、Webpack优化、JavaScript中的代码检查】(三)-全面详解(学习总结---从入门到深化)
81 2
下一篇
无影云桌面