从零搭建vue项目注意点总结

200 阅读3分钟

搭建vue项目,所需的相关包(包括loader -D)

  • webpack
  • webpack-cli
  • vue // 核心库文件 -S
  • vue-loader // 解析.vue文件
  • vue-template-compiler // 解析模板语法
  • html-loader // 解析html文件(模块处理),例如图片src的地址的解析转化
  • style-loader // 基础style样式解析
  • css-loader // css样式解析
  • sass // 解析sass核心
  • node-sass // 解析sass核心
  • sass-loader // sass or scss样式解析成css
  • babel-loader // 解析es语法为旧的js语法
  • @babel/core // babel核心库
  • @babel/preset-env // babel预设库,预设了一些解析配置项

package.json:

{
  "name": "vue-starter",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --config webpack.config.js --watch --mode=development"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.27.2",
    "element-ui": "^2.15.9",
    "vue": "^3.2.37",
    "vue-router": "^4.0.15"
  },
  "devDependencies": {
    "@babel/core": "^7.18.2",
    "@babel/preset-env": "^7.18.2",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "sass": "^1.52.2",
    "sass-loader": "^13.0.0",
    "scss-loader": "0.0.1",
    "style-loader": "^3.3.1",
    "vue-loader": "^17.0.0",
    "vue-template-compiler": "^2.6.14",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.9.2"
  }
}

webpack.config.js:

const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'), // output中的path只支持绝对路径
    filename: 'xycbundle.js',
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader',
      },
      {
        test: /\.s[ac]ss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'], // 数组写法时,越靠后的loader解析优先级越高
      },
      {
        test: /\.m?js$/,
        use: [
          {
            loader: 'babel-loader',
            options: { // 当需要对loader做一些配置时,采用对象写法,在options中进行配置
              presets: ['@babel/preset-env'],
            },
          },
        ],
      },
      {
        test: /\.html$/,
        loader: "html-loader",
      },
      {
        test: /\.(png|jpg|svg|gif)$/,
        // 老写法
        // use: [{
        //   loader: 'file-loader',
        //   options: {
        //     esModule: false,
        //   }
        // }],
        type: 'asset', // 使用类型为 asset 的 Asset Modules,webpack5.x 新写法,具体可参照文档中的Asset Modules,用于对文件以及引入资源模块的情况下的处理
        parser: {
          dataUrlCondition: {
            maxSize: 100 * 1024, // 小于 100kb 的文件将会被当作 asset/inline 类型对待,即会进行 base64 编码;否则会被当作 asset/resource 类型对待,即会被做单独的打包。最终把实际文件路径注入进去
          },
        },
        generator: { // 将资源文件打包进特定目录中,并重新命名
          filename: 'img/[name]_[hash:6][ext]', // 注意,这里 [ext] 获取到的扩展名前面已经带了 . 号
        },
      },
    ],
  },
  plugins: [new VueLoaderPlugin()], // 用于将所有其余的rules应用到vue-loader解析vue文件的过程中
}

最终build生成的目录如下:

image.png

一些优化操作

  • rules中的one of,避免每个文件每个rule都过一次
  • css、js等压缩插件
  • optimization中的splitchunk,用于对chunk进行切割、提取等优化操作
  • webpack5的缓存配置cache,首次编译之后,二次编译速度极大提升
  • webpack5的type资源模块assets/resource
  • 为loader指定include,减少loader应用范围,仅应用于最少数量的必要模块
  • 通过thread-loader将耗时的loader放在一个独立的worker池中运行,加快loader构建速度
  • tree-shaking
  • 文件名调整为contenthash,内容变化时文件名才会变化---浏览器缓存

一些优化调试工具:

const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const chalk = require('chalk') // 用于控制控制台打印文本样式的库
...
    new ProgressBarPlugin({
      format: `  :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`,
    }),
...

安装node环境控制包 cross-env

npm install cross-env -g

配置package.json,添加命令

"scripts": {
    ...
    "dev": "webpack --config webpack.config.js --watch --mode=development",
    "analyze": "cross-env WEBPACK_ANALYZE=true npm run dev"
    ...
  },

配置webpack.config.js

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const analyzer = new BundleAnalyzerPlugin({
  analyzerMode: 'server',
  //  将在“服务器”模式下使用的主机启动HTTP服务器。
  analyzerHost: '127.0.0.1',
  //  将在“服务器”模式下使用的端口启动HTTP服务器。
  analyzerPort: 8888,
  //  路径捆绑,将在`static`模式下生成的报告文件。
  //  相对于捆绑输出目录。
  reportFilename: 'report.html',
  //  模块大小默认显示在报告中。
  //  应该是`stat`,`parsed`或者`gzip`中的一个。
  //  有关更多信息,请参见“定义”一节。
  defaultSizes: 'parsed',
  //  在默认浏览器中自动打开报告
  openAnalyzer: true,
  //  如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成
  generateStatsFile: false,
  //  如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。
  //  相对于捆绑输出目录。
  statsFilename: 'stats.json',
  //  stats.toJson()方法的选项。
  //  例如,您可以使用`source:false`选项排除统计文件中模块的来源。
  //  在这里查看更多选项:https:  //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
  statsOptions: null,
  logLevel: 'info', // 日志级别。可以是'信息','警告','错误'或'沉默'。
})

//webpack其余配置,存入变量
const config = {...}
process.env.WEBPACK_ANALYZE ? config.plugins.push(analyzer) : null //根据环境变量,决定是否导入分析插件
module.exports = config

tips:三个size的区别:stat(输入)parsed(输出)gzip(压缩)github.com/webpack-con…

一些常用插件:

const HtmlWebpackPlugin = require('html-webpack-plugin')
...
    new HtmlWebpackPlugin({
      template: './src/index.html',//模板html文件
    }),
...
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
...
    new CleanWebpackPlugin(),
...

模板html文件,或者主css文件,规范未catch到的样式

* {
  padding: 0px;
  margin: 0px;
  box-sizing: border-box;
}
html,
body,
#app {
  width: 100%;
  height: 100%;
}

nginx配置

server { 
    listen 8080; # 端口号不要小于1024 
    root /home/service/app/project/dist; 
    location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|webp|tiff?|woff|woff2|mp3|m4a|aac|ogg|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ { 
        add_header Cache-Control no-cache; 
    } 
    location / { 
        expires -1; 
        try_files $uri /index.html; 
    } 
    gzip on; 
    gzip_types text/plain text/css text/xml application/javascript application/rss+xml application/atom+xml image/svg+xml; 
}