“This is the second day of my participation in the First Challenge 2022.

preface

While it’s rare to configure a project from zero to one in a real project, scaffolding integrates repetitive work that isn’t necessary. As a result, some developers rely too much on scaffolding without understanding its internal implementation process, so by configuring and building projects from zero to one we can better understand what scaffolding does for us in development.

The preparatory work

Creating a directory structure

Here, use the NPM init vite@latest command directly to generate the latest vue3 directory structure:

Of course, there are some tweaks to this directory:

  • willvite.config.jsSwitch towebpack.config.js: Because we are based onwebpack5Build the project
  • Initialize newpackage.json: the originalpackage.jsonWe rely on something we don’t need, so we delete it and reinitialize it
  • Get rid ofindex.htmlIn the<script type="module" src="/src/main.js"></script>Because this isviteYes, butwebpackDon’t need

Here is the adjusted directory structure:

Install base dependencies

Some basic dependencies are listed below, and others will be installed later when needed:

  • npm install vue@next
  • npm install webpack webpack-cli webpack-dev-server -D

rightwebpackPerform basic configuration.

// webpack.config.js

const path = require('path')

module.exports = {
    entry: {
        path: './src/main.js'
    },
    output: {
        filename: 'assets/js/[name].[contenthash:6].js'.path: path.resolve(__dirname, './dist')}}Copy the code

inpackage.jsonCreate a script in

// package.json

  "scripts": {
    "dev": "webpack server --mode=development"."build": "webpack --mode=production"
  }
Copy the code

Configure WebPack for different file types

Start the project

After the above preparations, we can start the project with the NPM run dev command, but you will find this error:

The.vue file is not recognized by Webpack, so we need to provide a loader to process it. This loader is mentioned in the official document:

Where @vitejs/plugin-vue is only required by Vite, so we only need vue-loader@next and @vue/ compiler-sFC

Note: Vue-loader handles vue2 by default, vue3 is used here, so install vue-loader@next

inwebpackIn the processing.vuefile

Install the required dependencies first via NPM install vue-loader@next @vue/ compiler-Sfc -d and then configure them in webpack.config.js:

// webpack.config.js

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

module.exports = {
   entry: {
       path: './src/main.js'
   },
   module: {
       rules: [{test: /\.vue$/,
               use: 'vue-loader'}},output: {
       filename: 'assets/js/[name].[contenthash:6].js'.path: path.resolve(__dirname, './dist')},plugins: [
     new VueLoaderPlugin(),
   ]
}
Copy the code

After the configuration is complete, we start the project with NPM run dev, and unsurprisingly you will get the following error:

inwebpackIn the processing<style></style>Style related content

NPM install style-loader css-loader -d install the required dependencies, and then configure them in webpack.config.js:

// webpack.config.js

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

module.exports = {
  entry: {
    path: './src/main.js',},module: {
    rules: [{test: /\.vue$/,
        use: 'vue-loader'}, {test: /.css$/,
        use: ['style-loader'.'css-loader'],},],},output: {
    filename: 'assets/js/[name].[contenthash:6].js'.path: path.resolve(__dirname, './dist'),},plugins: [
      new VueLoaderPlugin(),
  ]
}
Copy the code

Once the configuration is complete, start the project again with NPM run dev, and again you will get the following error:

This means that WebPack still does not recognize image-type files such as: . (PNG | JPG | jpeg | GIF), etc., then flashes here believe that you, thought about the need to use the file – loader/url – loader, but on this we don’t need to configure the two loader, because we are using the webpack5, It is time to use the module type of the asset Module.

configurationwebpackResource module

No more nonsense, directly on the official document instructions:

Here is the configuration of webpack.config.js:

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

module.exports = {
  entry: {
    path: './src/main.js',},module: {
    rules: [{test: /\.vue$/,
        use: 'vue-loader'}, {test: /\.css$/,
        use: ['style-loader'.'css-loader'],}, {test: /\.(png|jpe? g|gif)$/,
        type: 'asset/resource'.generator: {
          filename: 'assets/img/[hash][ext]'}}],},output: {
    filename: 'assets/js/[name].[contenthash:6].js'.path: path.resolve(__dirname, './dist'),},plugins: [
      new VueLoaderPlugin()
  ]
}
Copy the code

NPM run dev = NPM run dev

Visit the page content at this time:

Do you thinkDon’t panic It doesn’t matter it’s just not givenwebpackAfter packagingjsCode specifies the template.

Specify the template for Webpack

If you are familiar with webpack, you can probably guess that to use the html-webpack-plugin plugin, first install the html-webpack-plugin -d, then configure the webpack.config.js file:

const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: {
    path: './src/main.js',},module: {
    rules: [{test: /\.vue$/,
        use: 'vue-loader'}, {test: /\.css$/,
        use: ['style-loader'.'css-loader'],}, {test: /\.(png|jpe? g|gif)$/,
        type: 'asset/resource'.generator: {
          filename: 'assets/img/[hash][ext]'}}],},output: {
    filename: 'assets/js/[name].[contenthash:6].js'.path: path.resolve(__dirname, './dist'),},plugins: [
      new VueLoaderPlugin(),
      new HtmlWebpackPlugin({
          template: path.resolve(__dirname, './index.html')]}})Copy the code

At this point, it is passing againnpm run devStart the project and visit the page:

At this point, you have successfully configured a simple project based on vue3 and webpack5.

Optimizing the configuration file

Open the page console on F12 and you’ll see this warning message:

__VUE_OPTIONS_API__ and __VUE_PROD_DEVTOOLS__ are Boolean types, representing:

  • __VUE_OPTIONS_API__: Indicates whether the command is supportedoptions apiThe default istrue
  • __VUE_PROD_DEVTOOLS__: indicates whether to continue supporting the production packagedevtoolsPlug-ins, the default isfalse

Even if they have default values, we don’t have to set them, but Vue wants us to set these two configurations ourselves. After all, if Vue3 is fully embraced, there is no need to use the format of options API in writing, which will reduce the size of the package when packaging.

const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { DefinePlugin } = require('webpack')

module.exports = {
  entry: {
    path: './src/main.js',},module: {
    rules: [{test: /\.vue$/,
        use: 'vue-loader'}, {test: /\.css$/,
        use: ['style-loader'.'css-loader'],}, {test: /\.(png|jpe? g|gif)$/,
        type: 'asset/resource'.generator: {
          filename: 'assets/img/[hash][ext]',},},],},output: {
    filename: 'assets/js/[name].[contenthash:6].js'.path: path.resolve(__dirname, './dist'),},plugins: [
    new VueLoaderPlugin(),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './index.html'),}),new DefinePlugin({
      __VUE_PROD_DEVTOOLS__: false.__VUE_OPTIONS_API__: false,})],}Copy the code

The last

First look at the packaged directory structure via NPM run build:

Existing deficiencies:

  • jsFile not extracted, now alljsContent is packaged by defaultmain.hash.js
  • cssStyle related content is not extracted, the style is now all in<style></style>Tags are inserted in the form ofhtmlIn the file
  • .

Of course, there are also corresponding handling methods:

  • throughwebpackoptimizationOption configuration, extract the correspondingjs
  • throughmini-css-extract-pluginPlugins to extract the correspondingcss

The above are not configured one by one, when necessary, the corresponding configuration can be carried out.

At this point, we have successfully converted a project based on Vite + vue3 to a project based on WebPack5 + vue3.