7. 完成Vue项目构建前的准备工作

145 阅读2分钟

前面我们讲了对项目进行webpack模块化的改造,在改造过程中,我们也进行了各种webpack相关的性能优化,比如,对css和js文件的分离压缩,启动了开发模式,并抽象了公共模板。到现在这个项目其实已经优化的比较到位了,对平常的项目开发和项目上线都是可以满足的。

接下来,我们将进一步升级我们的项目,将我们的项目升级到vue的SPA项目,即vue的单页应用。

我相信很多同学可以初始化一个vue项目,但是很少有同学能拿当前的项目来改造成vue项目,这两者是有很大差别的。因为我们需要对vue的工程化进行一系列的改造。

目前,当我们开发的时候需要同时对html和js进行开发的,我们的逻辑写在js文件当中,但是DOM还是写在html中的。这种开发模式是比较陈旧的开发方式,开发效率是比较低的,我们看业务逻辑的是不是很清晰。而且,我们对业务做修改的时候,还需要对dom进行操作。所以现在的项目都会使用vue进行开发。

  1. 创建build目录,把webpack.config.js移到build目录中,开始做多配置文件改造

  2. 修改webpack.config.js中所有路径为绝对路径,完整配置如下:

const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CssMiniPlugin = require('css-minimizer-webpack-plugin')

module.exports = {
  mode: 'development',
  entry: {
    index: path.resolve(__dirname, '../src/index.js'),
    login: path.resolve(__dirname, '../src/login.js')
  },
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: 'js/[name].js',
    // 打包之前的删除dist目录
    clean: true
  },
  devServer: {
    static: {
      directory: path.join(__dirname, '../dist')
    },
    compress: true,
    port: 9000,
    hot: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024
          }
        },
        generator: {
          filename: 'images/[name].[hash:6][ext]'
        }
      },
      {
        test: /\.ejs$/,
        use: {
          loader: 'ejs-loader',
          options: {
            esModule: false
          }
        }
      }
    ]
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        extractComments: false
      }),
      new CssMiniPlugin({})
    ],
    splitChunks: {
      chunks: 'all',
      minSize: 30 * 1024,
      name: 'common',
      cacheGroups: {
        jquery: {
          name: 'jquery',
          test: /jquery\.js/,
          chunks: 'all'
        },
        'lodash-es': {
          name: 'lodash-es',
          test: /lodash-es/,
          chunks: 'all'
        }
      }
    }
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../src/img'),
          to: path.resolve(__dirname, '../dist/img')
        }
      ]
    }),
    new MiniCssExtractPlugin({
      filename: 'css/[name].css',
      chunkFilename: 'css/[name].chunk.css'
    }),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../src/index.html'),
      chunks: ['index']
    }),
    new HtmlWebpackPlugin({
      filename: 'login.html',
      template: path.resolve(__dirname, '../src/login.html'),
      chunks: ['login']
    })
  ]
}
  1. 修改package.json中的 script 命令
"scripts": {
  "start": "webpack-dev-server",
  "build": "webpack --config ./build/webpack.config.js"
}

接入vue

  1. 首先安装vue2.0
npm install -S vue@2.6.14
  1. 安装vue的编译库和对应loader
npm install @vue/compiler-sfc vue-template-compiler vue-loader@15  -D 
  • vue-loader的版本必须是15左右,因为需要和vue版本相对应;
  • vue-template-compiler用来编译.vue文件;
  • @vue/compiler-sfc对一些vue新特性进行编译
  1. 创建vue相关文件
  • 创建main.js
import Vue from 'vue'
import App from './App.vue'

new Vue({
  render: h => h(App)
}).$mount('#app')
  • 创建App.vue
<template>
  <div>
    {{ message }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'hello world'
    }
  }
}
</script>
  • 创建模板文件 public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>项目改造</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
  1. 创建build/webpack.vue.config.js,并写入下面配置
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CssMiniPlugin = require('css-minimizer-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

const config = {
  mode: 'development',
  entry: {
    index: path.resolve(__dirname, '../src/main.js')
  },
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, '../dist'),
    clean: true
  },
  devServer: {
    static: {
      directory: path.join(__dirname, '../dist')
    },
    compress: true,
    port: 9000,
    hot: true
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024
          }
        },
        generator: {
          filename: 'images/[name].[hash:6][ext]'
        }
      },
      {
        test: /\.ejs$/,
        use: {
          loader: 'ejs-loader',
          options: {
            esModule: false
          }
        }
      },
      {
        test: /\.vue$/,
        use: ['vue-loader']
      }
    ]
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        extractComments: false
      }),
      new CssMiniPlugin({})
    ],
    splitChunks: {
      chunks: 'all',
      minSize: 30 * 1024,
      name: 'common',
      cacheGroups: {
        jquery: {
          name: 'jquery',
          test: /jquery\.js/,
          chunks: 'all'
        },
        'lodash-es': {
          name: 'lodash-es',
          test: /lodash-es/,
          chunks: 'all'
        }
      }
    }
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../src/img'),
          to: path.resolve(__dirname, '../dist/img')
        }
      ]
    }),
    new MiniCssExtractPlugin({
      filename: 'css/[name].css',
      chunkFilename: 'css/[name].chunk.css'
    }),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../public/index.html'),
      chunks: ['index']
    }),
    new VueLoaderPlugin()
  ]
}

module.exports = config
  1. 修改package.json的script命令
"scripts": {
  "start": "webpack-dev-server",
  "start:vue": "webpack-dev-server --config ./build/webpack.vue.config.js",
  "build": "webpack --config ./build/webpack.config.js",
  "build:vue": "webpack --config ./build/webpack.vue.config.js"
}
  1. 执行npm run build:vue,打包成功。