从0到1:webpack5 搭建 Vue3 项目——开发环境

1,461 阅读6分钟

本文从0到1,使用 webpack5 搭建一个 Vue3 项目,一步一步完善,并对其中使用到的 plugin、loader 做出一些解释,让你对 webpack 有一个整体的认识。

本文使用的 NodeJS 版本为 16.15.1
可以从 GitHub 获取本文所对应的代码

起步

1、package.json 文件初始化

在项目文件夹下直接执行下面命令,创建 package.json 文件:

npm init -y

对于 package.json 文件中各个字段的解释,可直接查看 npm官方文档

2、安装 webpack、webpack-cli、webpack-dev-server

npm i webpack webpack-cli webpack-dev-server -D
  • webpack是真正执行打包工作的程序;
  • webpack-cliwebpack 的命令行接口,如果你想使用 npx 来运行 webpack,请确保你已经安装了 webpack-cli
  • webpack-dev-server 是在本地开发阶段,用来在本地起一个 server。

3、在根目录创建 webpack.config.js 文件,配置内容:

const path = require('path');
const { resolve } = path;

const config = {
  mode: 'production',
  entry: {
    main: './src/main.js'
  },
  output: {
    path: resolve(__dirname, 'dist'), // 打包后的文件输出的目录
    filename: `js/[name]_[chunkhash:8].js`, // 设置打包后的 js 文件名,如果在文件名前增加文件路径,会将打包后的 js 文件放在指定的文件夹下
  }
};

module.exports = config;

4、创建对应的 main.js 文件

在对应位置创建 main.js 文件

main.png

5、在 package.json 文件中添加 build 脚本:

"scripts": {
  "build": "webpack --config webpack.prod.js"
},

这个时候就已经可以执行 npm run build 指令了,会将 main.js 文件打包到 dist/js 文件夹下。

6、安装 @babel/core、@babel/cli、@babel/preset-env、babel-loader

在开发过程中,我们会使用到一些 js 的新语法,但是并不是所有浏览器都支持这些语法(有些用户的浏览器可能已经很多年没更新过了),这个时候就需要把新语法转化成ES5 语法,而完成这个工作的就是 babel

详细了解 babel 可访问这里

npm install --save-dev @babel/core @babel/cli @babel/preset-env babel-loader

@babel/cli 是一个命令行接口,如果不需要,可以不安装。

在项目的根目录下创建一个命名为 babel.config.json 的配置文件(需要 v7.8.0 或更高版本),并将以下内容复制到此文件中:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "edge": "17",
          "firefox": "60",
          "chrome": "67",
          "safari": "11.1"
        },
        "useBuiltIns": "usage",
        "corejs": "3.23.5"
      }
    ]
  ]
}

注意preset-env 后面的配置参数是从 babel 官网的示例中复制的,使用时需要根据自己项目需要来设置。

babel 在进行转换时,需要知道要转换成哪个目标语法,而 targets 就是告诉 babel 以这些浏览器的版本为目标进行转换,转换后的 js 代码,至少要能在这些浏览器的这些版本上运行。 当然,大部分项目里面不会在这里设置目标浏览器,更多的是使用 browserslist 来设置,后面我们也会使用到。

另外在使用 useBuiltIns 时,需要指定 corejs,所以,也需要安装对应版本的依赖: npm i core-js@3

在 webpack.config.js 中配置 babel-loader

  module: {
    rules: [
      // 它会应用到普通的 `.js` 文件
      // 以及 `.vue` 文件中的 `<script>` 块
      {
        test: /\.js$/,
        use: ['babel-loader'],
        exclude: /node_modules/
      }
    ]
  },

配置 babel-loader 时要注意,需要排除 node_modules 下面的文件,因为这里面的 js 文件,大多数情况下都是已经被编译过的,如果不排除,会导致它们又被 babel 编译,会报错;

7、安装 vue、vue-loader

使用 Vue3 时,不需要再安装 vue-template-compiler,Vue3 的包里面已经依赖了 @vue/compiler-sfc,而 vue-loader 里面就是用它来处理 .vue 文件的。

npm i vue vue-loader -D

配置 vue-loader

const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    // 请确保引入这个插件!
    new VueLoaderPlugin()
  ]
};

8、html-webpack-plugin

npm i html-webpack-plugin -D

这个插件是用来生成 index.html 文件的,我们可以指定一个模板文件,在打包的时候,会以这个模板文件为基础,生成项目的入口文件index.html,同时把打包后的 js 文件,以 <script> 标签的形式添加进这个 index.html 文件中。

配置

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
        template: path.resolve(__dirname, 'index.html'),
        filename: 'index.html',
        chunks: ['main'],
        inject: true,
        minify: {
          html5: true,
          collapseWhitespace: true,
          preserveLineBreaks: false,
          minifyCSS: true,
          minifyJS: true,
          removeComments: false
        }
      })
  ]
};

以上配置完成之后,已经可以启动一个 Vue 项目了,后面继续增加其它配置。

9、安装 style-loader、css-loader、sass、sass-loader

项目开发时,如果使用了 sass/less 这些预处理语言,就需要安装对应的预处理器和 loader,这里以 sass 为例。

npm i sass sass-loader css-loader style-loader -D
  • sass-loader - 加载 .scss/.sass 文件并把它们编译成 CSS ;
  • sass - sass 预处理器,sass 语法是由它来处理的;
  • css-loader - 处理 css 文件;
  • style-loader - 将 css 样式,以 style 标签的形式插入到当前页面中。

配置:

  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  },

10、安装 vue-router

npm i vue-router

创建 router/index.js 文件

import { createRouter, createWebHashHistory } from 'vue-router';

const Page1 = () => import('../views/Page1.vue');

const routes = [
  {
    path: '/',
    name: 'home',
    component: Page1
  }
];

const router = createRouter({
  history: createWebHashHistory(),
  routes
});

export default router;

需要修改 App.vue 文件,在里面添加一个 router-view 标签:

<div class="page">
  <router-view></router-view>
</div>

最后在 main.js 中将 router 对象添加到 app 实例上,

import { createApp } from 'vue';
import App from './App.vue';
import router from './router/index.js';

const app = createApp(App);
// 挂载路由
app.use(router);
app.mount('#app');

11、图片等资源的处理

在 webpack4 中,我们使用的是 url-loader 来处理页面中用到的图片资源,但在 webpack5 中,已经有内置的资源模块(asset module),所以我们不需要再去安装url-loader,直接使用内置的功能即可。 资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:

  • asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
  • asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现。
  • asset/source 导出资源的源代码。之前通过使用 raw-loader 实现。
  • asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现。
const config = {
  module: {
    rules: [
      // 使用 webpack 内置的资源模块,对图片资源的处理
      {
        test: /\.(jpg|png|gif|jpeg)$/,
        type: 'asset',
        generator: {
          // 设置图片被处理之后的名称,可以通过在名字前面加路径,将图片都放置在一个文件夹下,也可以通过 output.assetModuleFilename 来设置;
          // 注意这里的 [ext],它已经包含了 . ,所以不能再在[has:8] 和 [ext] 之间加上点了
          filename: 'img/[name]_[hash:8][ext][query]'
        },
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb,设置阈值,小于这个大小的,会被处理成 base 64 的字符串,默认是8kb
          }
        }
      },
      // 参考上面图片的处理方式,可以设置其它资源的处理方式
      // 视频、音频等
      {
        test: /\.(mp3|mp4|mov)$/,
        type: 'asset',
        generator: {
          filename: 'media/[name]_[hash:8][ext][query]'
        },
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024 // 4kb,设置阈值,小于这个大小的,会被处理成 base 64 的字符串,默认是8kb
          }
        }
      }
    ]
  },
};

12、postcss

在编写 css 样式时,针对不同的浏览器,需要在一些属性前添加对应的前缀,这个可以交给 postcss 来处理。

PostCSS 是一个允许使用 JS 插件转换样式的工具。 这些插件可以检查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 编译尚未被浏览器广泛支持的先进的 CSS 语法,内联图片,以及其它很多优秀的功能。 PostCSS 的 Autoprefixer 插件是最流行的 CSS 处理工具之一。

安装 postcss-loaderautoprefixer

npm i postcss-loader autoprefixer -D

修改 css、scss 的相关配置,添加 postcss-loader

{
  test: /\.css$/,
  use: ['style-loader', 'css-loader', 'postcss-loader']
},
// 应用到 scss 文件
{
  test: /\.scss$/,
  use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
},

在根目录下创建 postcss.config.js 文件,配置 postcss 使用到的插件:

module.exports = {
  plugins: [require('autoprefixer')]
};

也可以直接使用 postcss-preset-env,使用这个时,不需要再去安装 autoprefixer,因为这个预设里面已经依赖了它,在安装预设时,autoprefixer 就会被安装。

这里需要注意,给 css 添加前缀的是 autoprefixer

13、统一配置 browserslist

browserslist 文档:github.com/browserslis…

在前面我们使用 babel 时,需要指定我们打包时的目标浏览器,而在使用 autoprefixer 时,也需要指定目标浏览器,我们可以在根目录下创建.browserslistrc 配置文件,并配置目标浏览器,这样 babel 和 autoprefixer 都会使用这里的配置进行各自的处理。

也可以直接在 package.json 文件中,配置 browserslist 字段。

Browserslist 其实使用的是 Can I Use 来查询我们使用的语法是否在目标浏览器上可以使用。 在 node_modules/browserslist/package.json 文件中,可以在 dependencies 中看到,它依赖了一个叫caniuse-lite 的库。


以上就是开发环境所需要的配置,下一篇介绍生产环境的配置。

下一篇:从0到1:webpack5 搭建 Vue3 项目——生产环境