美文网首页
vue-cli3的单页面应用构建

vue-cli3的单页面应用构建

作者: afeng_1234 | 来源:发表于2018-11-19 11:00 被阅读0次
    前提全局安装 vue-cli :
    npm i -g @vue/cli@3.0.0-beta.6
    

    创建项目

    vue create my-project
    
    • default (babel, eslint) 默认套餐,提供 babeleslint 支持。
    • Manually select features 自己去选择需要的功能,提供更多的特性选择。比如如果想要支持 TypeScript ,就应该选择这一项。

    可以使用上下方向键来切换选项。如果只需要 babel 和 eslint 支持,那么选择第一项,就完事了,静静等待 vue 初始化项目。
    vue-cli 内置支持了8个功能特性,可以多选:使用方向键在特性选项之间切换,使用空格键选中当前特性,使用 a 键切换选择所有,使用 i 键翻转选项。

    对于每一项的功能,此处做个简单描述:
    • TypeScript 支持使用 TypeScript 书写源码。
    • Progressive Web App (PWA) Support PWA 支持。
    • Router 支持 vue-router
    • Vuex 支持 vuex
    • CSS Pre-processors 支持 CSS 预处理器。
    • Linter / Formatter 支持代码风格检查和格式化。
    • Unit Testing 支持单元测试。
    • E2E Testing 支持 E2E 测试。
    运行
    npm run serve
    
    .eslintrc.js 代码规范 配置文件
    module.exports = {
      root: true,
      env: {
        node: true
      },
      extends: ["plugin:vue/essential", "@vue/prettier"], //删除掉@vue/prettier 即取消eslint语法检查
      rules: {
        "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
        "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"
      },
      parserOptions: {
        parser: "babel-eslint"
      }
    };
    
    
    app.config.js 应用配置文件
    module.exports = {
      // 本地Express服务器的启动端口
      PORT: 3000,
      // 存放build结果的文件夹
      DIST_ROOT: 'dist',
      // 项目部署在服务器下的绝对路径,默认'/',参考https://cli.vuejs.org/zh/config/#baseurl
      BASE_URL: '/',
      // 生产环境下转为CND外链方式的npm包,键名是import的npm包名,键值是该库暴露的全局变量,参考https://webpack.js.org/configuration/externals/#src/components/Sidebar/Sidebar.jsx
      externals: {
        vue: 'Vue',
        'vue-router': 'VueRouter',
        vuex: 'Vuex',
        axios: 'axios',
        'element-ui': 'ELEMENT'
      },
      // CDN外链,会插入到index.html中
      cdn: {
        // 开发环境
        dev: {
          css: ['//at.alicdn.com/t/font_649543_1r02qafn5mm.css'],
          js: ['http://lunyu-1255697909.cos.ap-guangzhou.myqcloud.com/file-1950963/echarts.min.js']
        },
        // 生产环境
        build: {
          css: [
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/iconfont-pc/iconfont.css',
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/element-ui.css'
          ],
          js: [
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/vue.min.js',
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/vue-router.min.js',
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/vuex.min.js',
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/axios.min.js',
            'https://lcsoft-1255697909.cos.ap-guangzhou.myqcloud.com/lcsoft-cdn/element-ui.js',
            'http://lunyu-1255697909.cos.ap-guangzhou.myqcloud.com/file-1950963/echarts.min.js'
          ]
        }
      },
      // 生产环境是否使用预渲染
      productionPrerender: false,
      // 生产环境预渲染的路由
      prerenderRoutes: ['/', '/msg', '/mine'],
      // 生产环境是否使用Gzip
      productionGzip: true,
      // 生产环境需要Gzip压缩的文件
      productionGzipExtensions: ['js', 'css'],
      // scss资源文件,可以在里面定义变量,mixin等,使用时可以无需@import
      sassResources: ['color.scss', 'mixin.scss']
    }
    

    vue.config.js 覆盖 vue3.0 的node_model下的webpack配置

    const path = require('path')
    const chalk = require('chalk')
    const CompressionWebpackPlugin = require('compression-webpack-plugin')
    const PrerenderSPAPlugin = require('prerender-spa-plugin')
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
    
    const APP_CONFIG = require('./app.config')
    
    module.exports = {
      baseUrl: process.env.NODE_ENV === 'production' ? './' : APP_CONFIG.BASE_URL,
      outputDir: APP_CONFIG.DIST_ROOT + APP_CONFIG.BASE_URL, // prerendner会借助一个express服务器来预渲染,改变baseUrl后要保证这个模拟服务器能够找到所需的资源
      assetsDir: 'static',
      productionSourceMap: true,
      configureWebpack: () => {
        const myConfig = {}
        if (process.env.NODE_ENV === 'production') {
          // 1. 生产环境npm包转CDN
          myConfig.externals = APP_CONFIG.externals
          // 2. 使用预渲染,在仅加载html和css之后即可显示出基础的页面,提升用户体验,避免白屏
          myConfig.plugins = []
          APP_CONFIG.productionPrerender &&
            myConfig.plugins.push(
              new PrerenderSPAPlugin({
                staticDir: path.resolve(__dirname, APP_CONFIG.DIST_ROOT), // 作为express.static()中间件的路径
                outputDir: path.resolve(
                  __dirname,
                  APP_CONFIG.DIST_ROOT + APP_CONFIG.BASE_URL
                ),
                indexPath: path.resolve(
                  __dirname,
                  APP_CONFIG.DIST_ROOT + APP_CONFIG.BASE_URL + 'index.html'
                ),
                routes: APP_CONFIG.prerenderRoutes,
                minify: {
                  collapseBooleanAttributes: true,
                  collapseWhitespace: true,
                  decodeEntities: true,
                  keepClosingSlash: true,
                  sortAttributes: true
                },
                renderer: new Renderer({
                  inject: {
                    render: true
                  }
                }),
                postProcess (renderedRoute) {
                  /**
                   * 路由激活时,懒加载模块会自动注入
                   * 而预渲染的html中会注入懒加载模块的script标签,需剔除
                   * 这并不是一个非常严谨的正则,不适用于使用了 webpackChunkName: "group-foo" 注释的分组懒加载
                   */
                  renderedRoute.html = renderedRoute.html.replace(
                    /<script[^<]*chunk-[a-z0-9]{8}\.[a-z0-9]{8}.js[^<]*><\/script>/g,
                    function (target) {
                      console.log(
                        chalk.bgRed('\n剔除的懒加载标签:'),
                        chalk.magenta(`${target}`)
                      )
                      return ''
                    }
                  )
                  return renderedRoute
                }
              })
            )
          // 3. 构建时开启gzip,降低服务器压缩对CPU资源的占用,服务器也要相应开启gzip
          APP_CONFIG.productionGzip &&
            myConfig.plugins.push(
              new CompressionWebpackPlugin({
                test: new RegExp(
                  '\\.(' + APP_CONFIG.productionGzipExtensions.join('|') + ')$'
                ),
                threshold: 8192,
                minRatio: 0.8
              })
            )
        }
        if (process.env.NODE_ENV === 'development') {
          /**
           * 关闭host check,方便使用ngrok之类的内网转发工具
           */
          myConfig.devServer = {
            disableHostCheck: true
          }
        }
        return myConfig
      },
      chainWebpack: config => {
        /**
         * 添加CDN和配置文件htmlWebpackPlugin中
         */
        config.plugin('html').tap(args => {
          if (process.env.NODE_ENV === 'development') {
            args[0].cdn = APP_CONFIG.cdn.dev
            args[0].CONFIG_PATH = APP_CONFIG.BASE_URL + 'SYSTEM.CONFIG.js' // 开发环境读取项目更目录下的配置文件
          }
          if (process.env.NODE_ENV === 'production') {
            args[0].cdn = APP_CONFIG.cdn.build
            args[0].CONFIG_PATH = '/SYSTEM.CONFIG.js' // 生产环境读取服务器更目录下的配置文件
          }
          return args
        })
        /**
         * 将SYSTEM.CONFIG.js拷贝到根目录,使得本地的express服务器也能正确找到配置文件
         */
        config.plugin('copy').tap(args => {
          args[0].push({
            from: path.resolve(__dirname, 'public/SYSTEM.CONFIG.js'),
            to: path.resolve(__dirname, APP_CONFIG.DIST_ROOT),
            toType: 'dir'
          })
          return args
        })
        /**
         * 在每个scss文件无需使用@import即可引入变量或者mixin,也可以避免大量@import导致build变慢
         * sass-resources-loader 文档链接:https://github.com/shakacode/sass-resources-loader
         */
        const webpackScssMap = config.module.rule('scss').oneOfs.store
        webpackScssMap.forEach(item => {
          item
            .use('sass-resources-loader')
            .loader('sass-resources-loader')
            .options({
              resources: APP_CONFIG.sassResources.map(file =>
                path.resolve(__dirname, 'src/style/' + file)
              )
            })
            .end()
        })
      }
    }
    
    

    相关文章

      网友评论

          本文标题:vue-cli3的单页面应用构建

          本文链接:https://www.haomeiwen.com/subject/ztzbfqtx.html