webpack一篇就够!

准备工作

首先必须保证本地安装了nodejs,因为webpack是构建在其之上,请参考官网。下载最新的LTS,也就是长期维护版,像安装其他软件一样,狂按下一步即可,完成之后打开命令行工具,也就是cmd

node -v
npm -v
复制代码

通过上面两条命令即可得到node以及npm的版本信息,注意:npmnode的包管理工具。

58FDFC0F-6D11-465B-95FF-2B8031104EC9.png

安装

在安装webpack的时候一般有两种情况:全局本地工作目录。二者的区别便是,通过全局安装的webpack可以在计算机任何目录执行webpack命令,而后者只能在当前工作目录执行。

在安装的时候我们通常会安装2个包:webpackwebpack-cli,前者是wepack主包,后者可以在命令行里面执行webpack命令。

全局安装

下面就开始全局安装webpack

npm install webpack webpack-cli --global
复制代码

上面是完整的命令行代码,也可通过下面的简写模式。

npm i -g webpack webpack-cli
复制代码

这里需要注意的是,在使用mac的小伙伴,一定要记得在最前面加上sudo

sudo npm i -g webpack webpack-cli
复制代码

按照提示输入电脑的登陆密码即可。

安装完成后,通过webpack -v来查看下相关信息。

AD70D233-F002-4522-A2DD-D427BC602968.png

到这里,webpack全局安装就完成了,但是在实际工作中还是不大推荐这种形式,这样会让你所有项目锁定一个webpack版本,而且在运行不同webpack版本项目会导致构建失败。

为了更加灵活且避免一些不必要的错误,在实际工作中还是推荐在当前工作目录下安装,这样就算换了一台电脑也不会出现问题。

本地工作目录安装

在开始之前,需要先创建一个工作目录,并且初始化一个node的配置文件,也就是我们常见的package.json

npm init -y
复制代码

这样就会在项目根目录自动创建好package.json文件。

接下来,就开始在当前目录执行如下命令:

npm install webpack webpack-cli --save-dev
//简写
npm i -D webpack webpack-cli
复制代码

到此,本地安装就完成了,我们就可以在当前目录下执行webpack命令。

运行

为了方便我们测试简单的webpack打包,我们先创建2个js文件。

src/c1.js

c1.js中,我们通过export默认导出一个add函数。

export default function add (a, b) {
  console.log(`a+b=${a + b}`);
}
复制代码

src/index.js

index.js中,我们通过import引入c1.js导出的add函数,并进行一次调用。

import add from './c1.js'
add(3, 4)
复制代码

通过在当前目录下执行webpack命令,这时候会自动创建一个dist目录,里面包含一个main.js,这就是webpack为我们打包出来的js代码。

仔细思考一下,我们貌似并没有配置什么,也就是单纯的安装了webpack必须的两个依赖包,那到底webpack是依据什么来进行打包的?

webpack --stats detailed
复制代码

执行上述命令,我们就可以看到详细的webpack打包信息了。

思考:这时候在命令行执行的webpack命令是全局的还是当前目录下的呢?

为了测试这一结果,我们卸载掉全局的webpack

npm uninstall --global webpack webpack-cli
复制代码

然后,我们再次在工作目录下执行webpack指令,我们会发现,webpack找不到了,这就说明,我们刚才执行的指令是全局指令。

2F25E651-AFC4-4947-B29F-BDAF89F7422F.png

如果我们没有全局的webpack,是不是这个项目就没法构建了?不是的,这时候我们可以使用npx来执行webpack命令。

npx webpack
复制代码

392D2498-3D72-499C-9A9D-6542C77E5D9D.png

这时候,我们又能正常进行打包了。

有小伙伴这时候可能就有疑问了,npx到底是什么?居然有如此魔法,那他到底使用的是哪里的webpack

npxnpm5.2之后发布的一个命令,简单理解就是我们可以用npx来执行各种命令,npx会默认从当前目录去查找有没有webpack,如果没有就会依次往上一层去寻找,而这时候我们当前目录正好有webpack,所以,npx就会执行当前目录下的webpack

到这里,webpack的准备工作以及如何运行就介绍完了,但是我们还并不会去控制webpack按照我们的需求来进行构建,例如,我要以哪个文件为入口,我要将打包文件放在哪里等等。接下来我们就逐步介绍webpack的配置文件。

配置

webpack默认提供了两种配置形式:终端命令配置文件

终端命令

webpack给我们提供了丰富的命令行指令,通过webpack --help来查看。

接下来,我们小试牛刀,来看看常用的命令行指令。

例如:我们要指定入口为:src/index.js,并且指定modeproduction

npx webpack --entry ./src/index.js --mode production
复制代码

这样,我们会看到再次生成dist/main.js,如果我们想自定义目录以及生成的文件名呢,这时候我们需要配置其他参数,这样一来,我们的命令会变得非常长,这样肯定不是最好的方案,webpack也给我们提供了另外一种配置方案,通过webpack.config.js来配置这些打包信息。

配置文件

首先,在项目根目录创建webpack.config.js文件(不可更改文件名),配置文件默认采用的是commonjs语法,通过module.exports导出一个配置对象,webpack会自动去读取该配置文件。

const path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist') //这里必须用path处理路径,否则报错。
  },
  mode: 'none' //指定开发模式,避免控制台报错。
}
复制代码

上面就是一个最基本的webpack的配置文件,指定了入口,出口以及开发环境,当我们再次执行:npx webpack,也会生成dist/bundle.js

难道webpack就这点能耐?接下来我们开始了解webpack的插件,这样可以简化我们的开发流程。

插件

我们可以把webpack想象成一条生产线,入口文件我们就想象成原材料,中间会经过各种工序才能生产出我们需要的成品,而这中间有可能会用到各种工具来辅助,我们就可以把webpack的插件想象成这些工具。

下面我们来介绍几种工作中常用的插件。

HtmlWebpackPlugin

在实际工作中,我们肯定不仅仅是为了生成一个js文件这么简单,我们还需要将生成的js文件自动引入html中才算完美,不然每次还要手动去引入,稍不注意还会出错,这个插件就是为了解决我们这个问题。

首先,当然是安装插件:

npm i -D html-webpack-plugin
复制代码

安装完之后,我们当然要在webpack.config.js中配置该插件。

...
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin()
  ]
}
复制代码

再次执行:npx webpack,这时候在dist目录下不仅仅只有一个bundle.js了,还有一个index.html,并且已经自动引入我们生成的js文件,在浏览器中打开html文件,js也是可以正常运行的。

我们打开生成的index.html发现里面的代码都是插件给我们自动生成的,可恶的控制欲不能忍受不可控的代码,我们能让他按照我们提供的html格式生成文件吗?当然是可以的!

new HtmlWebpackPlugin({
  template: 'index.html', //模板文件
  filename: 'app.html', //生成的html文件名称
  inject: 'body' //js插入的位置,默认在head。
})
复制代码

这样,我们就可以为所欲为了。

再次打开熟悉的dist目录,除了之前的html文件,又给我们生成了新的app.html,之前的html文件自然就没用了,总不能每次要我们手动去删除吧,当然不行,文件少还行,万一来个几十上百个无用文件,不说了,手抖。

清理dist

要在每次打包之前都清理掉之前的旧文件,只需要在output中配置clean属性即可。

output: {
  ...,
  clean: true
}
复制代码
使用 source map

这时候,我们故意写个错误的语法,

修改src/index.js

...
cosole.log('hhh');
复制代码

webpack.config.js配置文件中的mode改成development,再次执行:npx webpack,并且在浏览器打开dist/app.html

54078A9C-CB3A-41D5-9018-734BF1935DAB.png

8ADC79B8-4573-4733-9363-C0EA40A5864D.png

我们可以发现他并不能指向我们源码中的错误位置,这对我们开发调试来说简直太难了。

接着,我们修改webpack.config.js,配置devtool为:inline-source-map,并再次执行打包,并刷新浏览器。

module.exports = {
  ...,
  devtool: 'inline-source-map'
}
复制代码

1370904F-6759-402D-9C74-EBF009F1375D.png

CDA6644D-B842-4CFA-80B7-FA1168CF5806.png

这次就正确的指出了错误语法的位置了。

思考:不知小伙伴注意到没有,我们每需改一次都要手动执行npx webpack,这哪里是前端自动化,这跟工地搬砖有啥区别,那怎样可以一劳永逸,很简单,执行:npx webpack --watch,给webpack加个监工不就是了,这样只要我们的项目有文件改变了,就会自动执行打包。

自动打包解决了,可每次我们还是要手动刷新一下浏览器才能看到最新的结果,这显然不是我们所期待的。

搭建开发环境

webpack-dev-server就是用来解决我们上一个痛点,通过它可以在我们本地启动一个服务器,并且可以实现实时刷新。

安装 webpack-dev-server

npm i -D webpack-dev-server
复制代码

修改webpack.config.js

module.exports = {
  ...,
  devServer: {
    static: './dist'
  }
}
复制代码

执行npx webpack-dev-server,这时候就会自动启动一个server

B59EDC7F-43F8-41E9-96E9-FAD19B228AC5.png

在浏览器打开:http://localhost:8080

真相:webpack-dev-server并不需要dist目录的文件,而是直接读取的内存,所以就算我们删掉dist目录也依然能正常访问。

资源模块

webpack除了可以打包我们的js文件,还可以打包其他文件吗?例如:字体图片等等,在这之前,我们通常用gulp或者grunt来处理我们的资源文件,将资源移动到dist或者build,其实webpack最为出色的除了引入js还可以使用内置的资源模块(asset modules)来引入任何其他类型的资源。

资源模块类型分为如下4种:

asset/resource: 发送一个单独的文件并导出URI

asset/inline:导出资源的Data URI

asset/source:导出资源的源代码

asset:会在导出一个URI和发送一个单独的文件之间自动选择

猜你喜欢

转载自juejin.im/post/7047436439889379342