Skip to content
本文总阅读量

1、vue-cli 构建后 index.html 输出时间

为了方便测试不用退出登录查看登录页下标版本号信息

vue.config.js 配置

js
chainWebpack: (config) => {
  config.plugin('html').tap((args) => {
    args[0].date = new Date().toLocaleString()
    return args
  })
}

public/index.html 修改

html
<html date="<%= htmlWebpackPlugin.options.date %>"

2、vue-cli 项目 index.html 中 script 引用外部 js 文件踩坑

vconsole

js
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
 // VConsole 默认会挂载到 `window.VConsole` 上
<script>var  vConsole = new  window.VConsole();</scipt>

dayjs

js
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script>window.dayjs().format()</scipt>
<!-- 这样用 <script>dayjs().format()</scipt>  会报错Uncaught ReferenceError: dayjs is not defined -->

3、driver.js 页面引导

不在 mounted 中调用,在 click 事件中触发出现闪屏或者没反应

 click改为click.stop即可

4、live-server 临时服务器

这是一个具有实时重载功能的小型开发服务器。使用它来破解你的 HTML/JavaScript/CSS 文件,便于打包后的项目调试 全局安装

npm install -g live-server

默认运行 index.html,端口 8080,dist 下运行

live-server

5、关于 audio 自动播放问题

vue 前端 js audio 标签 浏览器自动播放问题

错误提示

因为用户没有与浏览器产生交互,如点击等 control.vue?6752:186 Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

代码尝试

文档

测试部分浏览器/参数设置可以

火狐浏览器、chrome 浏览器需要设置 360 浏览器不用任何设置就能自动播放

6、Three.js

vue2.6 + vue-cli

js
var TextureLoader = new THREE.TextureLoader()
// 本地图片资源    ** 报错 一片黑色,图片不显示 **
var texture = TextureLoader.load('@/images/world-surface.jpg')
this.material = new THREE.MeshLambertMaterial({
  map: texture
})
this.mesh = new THREE.Mesh(this.geometry, this.material) //网格模型对象Mesh
this.scene.add(this.mesh) //网格模型添加到场景中

查看信息发现找不到图片资源

解决本地图片资源 需要使用 require() 转换下

var texture = TextureLoader.load(require('@/assets/earch.webp'))

网络图片资源

var texture = new THREE.TextureLoader().load('http...')

7、地图利用定时器轮询渲染数据标记导致内存溢出、页面卡顿

两个不同版本 webgl 和 v3

  • 传统版本的命名空间为 BMap,比如:new BMap.Map('container')
  • WebGL 版本的命名空间为 BMapGL,比如:new BMapGL.Map('container') 建议使用 WebGL,因为和文档 demo 保存一致,3.0 的 library 是开放性的源码,可自行进行修改使用的,后续也将不再更新新功能了

文档 demo类参考工具类三维参考鼠标绘制

浏览器长期挂着页面失去响应

1、利用浏览器内存快照排查闭包对象释放、addEventListener 监听对象移除、定时器移除等 2、用 requestAnimationFrame 替换 setInterval、setTimeout 进行轮询

排查问题

js
// 实例化Demo this.startMark = this.defaultMarker(point) // 变量引用不当 defaultMarker(point) { if (!point) return null let markerIcon = new
BMapGL.Icon(imagePath, new BMapGL.Size(34, 48)) let marker = new BMapGL.Marker(point, { icon: markerIcon }) marker.isLock = true
marker.addEventListener('click', function()) map.addOverlay(marker) // 将标注添加到地图中 return marker } // 导致占用内存对象需要清空变量 this.startMark.isLock
= false map.removeOverlay(this.startMark) this.startMark = null
js
// 清空地图覆盖物释放对象 cleanBMapOverlay() { let list = map.getOverlays() list = list.filter(item => !item.isLock) list.forEach(marker => {
marker.removeEventListener('click', function()) // 解绑事件监听器 map.removeOverlay(marker) // 从地图上移除标记 marker = null //
将对象置为null以便垃圾回收机制释放内存空间 }) // map.clearOverlays() 强制清空 }

8、css 直接读取 data 内容

动态 attribute 名 (2.6.0+)

9、给 ElementUI 包添加补丁

插件版本
nodev14
npmv8.19.4
patch-packagev8.0.0
element-uiv2.15.7

patch-package 文档

安装

npm i patch-package

对 TimePicker 组件修改限制结束时间需要间隔一分钟

使用 npx patch-package package-name

  • package-name 对应修改后的包名
  • 在根目录自动创建 patches

在 package.json 的 script 中添加如下字段及内容在 npm install 后执行

vue
{ "postinstall":"patch-package" }

10、vue-cli 创建的 webpack5 环境脚手架配置 Node.js 核心模块

安装插件 node-polyfill-webpack-plugin

npm install node-polyfill-webpack-plugin

vue.config.js 文件

js
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
const Timestamp = new Date().getTime()

module.exports = defineConfig({
  configureWebpack: (config) => {
    // 在Webpack中填充Node.js核心模块。此模块仅用于Webpack 5+。
    config.plugins.push(new NodePolyfillPlugin())
    // 屏蔽node内置fs,child_process模块
    config.resolve.fallback = {
      fs: false,
      child_process: false
    }
    // 输出js添加时间戳避免出现缓存问题
    config.output.chunkFilename = `[name].${Timestamp}.js`
  }
})

11、重构旧vue2项目 vue-cli@2.9.6升到vue-cli@5.0.8

vue.config.js

node = v14.16.1 npm = 6.14.12

  • node-polyfill-webpack-plugin webpack3支持node.js核心模块,webpack5不支持,如果插件中有依赖需要则要安装 configureWebpack.resolve.fallback 可忽略部分

configureWebpack

  • plugins 支持 new webpack.ProvidePlugin 自动加载模块

  • externals 外部依赖减少依赖大小

  • [Bug Report] $attrs is readonly $listeners is readonly configureWebpack.resolve.alias 配置 vue$: 'vue/dist/vue.esm.js'

  • 去掉部分依赖dns等

package.json

js
{
  "name": "vue-cli_v5_webpack",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "lint": "vue-cli-service lint",
    "serve:dev": "vue-cli-service serve --mode development",
    "serve:test": "vue-cli-service serve --mode test",
    "serve:prod": "vue-cli-service serve --mode production",
    "build:dev": "vue-cli-service build --mode development",
    "build:test": "vue-cli-service build --mode test",
    "build:prod": "vue-cli-service build --mode production",
    "prettier": "prettier --config ./.prettierrc.js --write \"./**/*.{js,vue}\" "
  },
  "lint-staged": {
    "*.{js,vue,ts,jsx,tsx}": [
      "prettier --write"
    ],
    "*.{html,css,less,scss,md}": [
      "prettier --write"
    ]
  },
  "dependencies": {
    "axios": "^1.6.8",
    "compressorjs": "^1.2.1",
    "core-js": "^3.36.1",
    "crypto": "^1.0.1",
    "crypto-js": "^4.1.1",
    "echarts": "^4.1.0",
    "element-ui": "^2.15.6",
    "file-saver": "^2.0.5",
    "jquery": "^3.3.1",
    "js-file-download": "^0.4.1",
    "js-md5": "^0.7.3",
    "moment": "^2.29.4",
    "node-polyfill-webpack-plugin": "^3.0.0",
    "path": "^0.12.7",
    "qs": "^6.5.1",
    "quill": "^1.3.6",
    "vue": "^2.6.14",
    "vue-quill-editor": "^3.0.6",
    "vue-router": "^3.2.0",
    "vuedraggable": "^2.16.0",
    "vuex": "^3.4.0",
    "vuex-persistedstate": "^2.5.4",
    "xlsx": "^0.18.5"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "css-loader": "^6.10.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "prettier": "^3.2.5",
    "sass": "^1.72.0",
    "sass-loader": "^14.1.1",
    "vue-template-compiler": "^2.6.14",
    "webpack-bundle-analyzer": "^4.10.1",
    "webpack-node-externals": "^3.0.0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ],
  "volta": {
    "node": "14.21.3"
  }
}

vue.config.js

js
const { defineConfig } = require('@vue/cli-service')
const webpack = require('webpack')
const path = require('path')
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = defineConfig({
  lintOnSave: false,
  transpileDependencies: true,
  configureWebpack: {
    externals: [  // 外部依赖
      {
        AMap: 'AMap',
        AMapUI: 'AMapUI',
        lodash: 'loadsh'
      }
    ],
    resolve: {
      fallback: {
        fs: false
      },
      alias: {
        vue$: 'vue/dist/vue.esm.js',
        '@': path.resolve(__dirname, 'src'),
        '@public': path.resolve(__dirname, 'public'),
        '@static': path.resolve(__dirname, 'static'),
        common: path.resolve(__dirname, 'src/common'),
        excel: path.resolve(__dirname, 'src/js/excel')
      }
    },
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'windows.jQuery': 'jquery'
      }),
      new NodePolyfillPlugin(),
      new BundleAnalyzerPlugin({
        openAnalyzer: false
      })
    ]
  },
  chainWebpack: (config) => {}
})

12、重构旧vue2项目 vue-cli@5.0.8升到vite@2.9.10

vite@3开始不支持vue2

vite.config.js

注意文档只有英文,中文是最新的版本

  • 修复所有导入的单个文件组件都要以扩展名结尾 resolve.extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']

  • vite-plugin-node-polyfills 支持node.js核心模块

  • vite-plugin-vue2 和 vite-plugin-vue2-jsx 不能同时使用 引入vite-plugin-vue2-jsx即可,最高支持vite@2

  • element-theme 样式

引入方式 ~ 改 为node_modules

js
$--color-primary: #32B5BE;
/* 改变 icon 字体路径变量,必需 */
$--font-path: 'node_modules/element-ui/lib/theme-chalk/fonts';
@import "node_modules/element-ui/packages/theme-chalk/src/index";

报错

Deprecation Warning: $weight: Passing a number without unit % (0) is deprecated.

消除 node_modules\element-ui\packages\theme-chalk 的scss警告 npm install sass@1.26.2

想用import引入CommonJs模式的文件

import foo from './foo.js'

js
var foo = 'Hello, world!'
module.exports = foo

报错

vite Pre-transform error: Failed to resolve import "commonjsHelpers.js"

降低 npm install @rollup/plugin-commonjs@21.1.0

  • 外部依赖减少依赖大小 cdn方式引入直接挂载在window
js
  optimizeDeps: {
    exclude: ['loadsh'],
    entries: ['AMap', 'AMapUI']
  }

package.json

js
{
  "name": "vite-ptkc",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "vite --mode development",
    "build": "vite build --mode development",
    "serve": "vite preview",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
  },
  "lint-staged": {
    "*.{js,vue,ts,jsx,tsx}": [
      "prettier --write"
    ],
    "*.{html,css,less,scss,md}": [
      "prettier --write"
    ]
  },
  "dependencies": {
    "@rollup/plugin-commonjs": "^21.1.0",
    "axios": "^1.6.8",
    "compressorjs": "^1.2.1",
    "crypto": "^1.0.1",
    "crypto-js": "^4.1.1",
    "echarts": "^4.1.0",
    "element-ui": "^2.15.6",
    "file-saver": "^2.0.5",
    "jquery": "^3.3.1",
    "js-file-download": "^0.4.1",
    "js-md5": "^0.7.3",
    "moment": "^2.29.4",
    "path": "^0.12.7",
    "qs": "^6.5.1",
    "quill": "^1.3.6",
    "vue": "^2.5.2",
    "vue-quill-editor": "^3.0.6",
    "vue-router": "^3.2.0",
    "vuedraggable": "^2.16.0",
    "vuex": "^3.4.0",
    "vuex-persistedstate": "^2.5.4",
    "xlsx": "^0.18.5"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vitejs/plugin-vue": "^1.6.1",
    "@vue/eslint-config-prettier": "^6.0.0",
    "eslint": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-vue": "^8.0.1",
    "prettier": "^2.2.1",
    "sass": "^1.26.2",
    "vite": "^2.9.10",
    "vite-plugin-node-polyfills": "^0.21.0",
    "vite-plugin-vue2-jsx": "^1.0.3",
    "vue-template-compiler": "^2.5.2"
  },
  "volta": {
    "node": "18.20.2"
  }
}

vite.config.js

js
import { defineConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
import { createVuePlugin as vue } from 'vite-plugin-vue2-jsx'
const path = require('path')

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), nodePolyfills()],
  resolve: {
    alias: {
      vue$: 'vue/dist/vue.esm.js',
      '@': path.resolve(__dirname, './src'),
      '@public': path.resolve(__dirname, 'public'),
      '@static': path.resolve(__dirname, 'static'),
      common: path.resolve(__dirname, 'src/common'),
      excel: path.resolve(__dirname, 'src/js/excel')
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] // 修复所有导入的单个文件组件都要以扩展名结尾
  },
  // 外部依赖
  optimizeDeps: {
    exclude: ['loadsh'],
    entries: ['AMap', 'AMapUI']
  }
})