Vue 项目之 Webpack 的基础打包(4)

483 阅读6分钟

「这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

1. 创建局部的 webpack

前面我们直接执行 webpack 命令时,使用的其实是安装在了全局的 webpack。但使用全局的 webpack 会存在一个问题:如果我们有多个项目,它们原来依赖的 webpack 版本和全局的 webpack 版本不一致,此时使用全局的 webpack 分别对它们进行打包,由于使用的 webpack 版本和它们原来依赖的 webpack 版本不同,因此可能存在兼容性问题:

使用全局 webpack 可能存在的问题.png

因此,真实开发中,我们通常很少使用全局的 webpack 去打包某个项目,而是会为每个项目单独安装某个版本的 webpack,也就是说每个项目都有属于自己的某个版本的 webpack,在打包项目时使用的也是该项目中的 webpack。因此,我们需要局部(local)安装 webpack,也就是在项目中安装 webpack。(前面全局安装 webpack 只是为了便于演示,后面我们都会使用局部安装的 webpack。)

那我们该如何在项目中安装和使用 webpack 呢?首先,我们需要知道,我们安装的 webpackwebpack-cli 都是一个包(package),后期我们还会根据项目的需要安装更多的包,因此,项目中会有一大堆的包,那这些包怎么管理呢?通常我们会在项目的根目录下创建一个文件:package.json,这个文件可以用来帮助我们管理包依赖以及记录一些项目的信息。

创建这个 package.json 文件有两种方式:

  • 如果项目根目录名称中存在中文,只能使用如下命令进行创建:

    npm init
    

    执行这条命令后,我们需要根据提示信息一步一步进行操作,除了第一步需要给包名重新命名为不包含中文的名字,后续的步骤可以一直敲回车即可:

    image-20211029075144987

  • 如果项目根目录名称中不存在中文,还可以使用如下命令进行创建:

    npm init -y
    

    这条命令可以帮助我们跳过具体步骤,使用默认配置,直接生成 package.json 文件:

    image-20211029075313680

使用命名生成 package.json 文件后,我们就能在项目根目录下看到它了:

image-20211029080216106

有了这个 package.json 文件之后,我们在项目目录下运行下面的命令局部安装 webpack

npm install webpack webpack-cli -D

上面的命令中,-D--save-dev 的缩写,意思是作为开发时依赖(即在开发阶段会使用到)进行安装,所安装的包会在 package.jsondevDependencies 中出现。而如果不加 -D,直接运行:

npm install webpack webpack-cli

则作为生产时依赖(即除了在开发阶段,生产阶段也会使用到,就是说跑在用户那边的代码也需要用到的包)进行安装,所安装的包会在 package.jsondependencies 中出现。

对于 webpack 来说,我们只需要在开发阶段用它打包代码,用户那边使用我们的代码时就不再需要 webpack 了,因此,我们添加开发时依赖的标记(-D)安装它。而对于 vuevuexvue-routeraxios 等后期我们会使用到的包,由于用户在浏览器上运行我们的代码时也需要用到它们,所以它们就属于生产时依赖,我们在安装它们时就不需要添加 -D 标记(flag)了。

需要说明的是,对于开发依赖和生产依赖的区分是一种规范,虽然可以不按规范来做,但还是建议按照规范正确区分开发时依赖和生产时依赖后进行包的安装。

回到我们这里,因为 webpackwebpack-cli 都是开发时依赖,所以我们执行的命令要加 -D 标志(flag)。

局部安装完成后,我们就会发现项目目录下多出了一个 node_modules 文件夹和一个 package-lock.json 文件:

  • node_modules 文件夹中存放的是项目中安装的所有依赖包,当前就是我们刚才安装的 webpackwebpack-cli 这两个包以及这两个包所依赖的其它包;
  • package-lock.json 文件记录着项目中所有依赖的真正的版本号信息,并且在我们下次安装时,它可以去缓存中寻找压缩文件(后面会解压到 node_modules 文件夹中);

有了局部安装的 webpack,我们该怎么使用它呢?还是像之前那样直接敲 webpack 命令打包吗?答案是否定的。因为只要是直接敲 webpack 命令,都会去使用全局的 webpack 进行打包。要想使用局部的 webpack 进行打包,我们需要使用 node_modules/.bin 下的 webpack 命令。那怎么样找到这条命令呢?有两种方式:

  • 直接用该命令的路径执行该命令,比如在当前项目目录(basic_webpack)下,以如下方式运行该命令:

    ./node_modules/.bin/webpack
    
  • 前面这种方式需要手动地一层层去找,有点麻烦,因此 npm 工具给我们提供了一个命令:npx,这个命令在执行它后面的命令时,会优先去找 node_modules/.bin 下的对应的命令,比如当我们执行下面的命令时,就会去 node_modules/.bin 下寻找 webpack 命令来运行,同样能正常打包:

    npx webpack
    

    image-20211031100620362

但使用 npx 直接执行 node_modules/.bin 下的某个命令,我们可能并不是特别熟悉。所以开发中我们一般会这样做:

  • 在项目目录下的 package.json 文件中,有一个 scripts,里面默认有一行 "test": "echo \"Error: no test specified\" && exit 1",我们把这行删掉,然后写上 "build": "webpack"

    image-20211031103052219

    那就意味着,之后我们可以执行这个 build 脚本(script),接着这个脚本就会自动去执行 webpack 命令。那不对呀,这里的 webpack 前面怎么没有加 npx 呢?是的,写在这里的命令,前面可以不加 npx,因为它会自动去 node_modules/.bin 目录下寻找对应的命令。

  • 然后,当我们想要执行这条 build 脚本时,就可以在命令行中这样做:

    npm run build
    

    run 就是运行的意思,build 是脚本的名称,合起来就是运行 build 脚本的意思。以后如果有一个脚本叫 serve,那么就执行 npm run serve 来运行它。

    执行 npm run build 命令(执行命令前可以先把之前打包生成的 dist 文件夹删掉,便于查看之后的打包结果)之后,我们可以看到,依然是可以正常打包的:

    image-20211031105351156

    而且,回到浏览器网页上,打开控制台,跟刚才的效果也是一样的。

以上,就是局部安装 webpack 以及使用它进行打包的过程。