近期有新项目开发,使用vue-cli3.7 进行项目构建,形式上跟vue-cli2.x 区别还是蛮大的。最主要的就是生成的项目中,进行webpack配置的文件没有了。这是因为在这个版本的cli中,作者将绝大部分相同的webpack配置,已经封装到cli的安装包中。我们可以打开 node_modules/_@vue_cli-service@3.7.0@@vue/cli-service 文件夹看一下,参考图片:

这块就比较眼熟了,就类似于 vue-cli2.x 生成的项目目录中webpack的相关配置。打开各个文件后发现也确实是webpack的各种配置,只不过设置属性的时候,采用了webpack 提供的各种方法的链式调用。

虽然3.x的脚手架封装了webpack绝大部分配置,使得生成的项目更加清晰,但是在开发中免不了会有自己的个性需求,来添加一些自己的项目配置,此时只需在项目的根目录下新建一个vue.config.js文件即可,内容如下:

 

module.exports = {
   //打包文件输出路径,即打包到哪里
  outputDir: 'dist',
  // 静态资源地址
  assetsDir: 'static',
  // eslint-loader 是否在保存的时候检查
  lintOnSave: false, 
  // 生产环境是否生成 sourceMap 文件
  productionSourceMap: false, 
  filenameHashing: true, //文件hash

  // chainWebpack 这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则
  // 和具名插件,可以通过其提供的一些方法链式调用,在cli-service中就使用了这个插件
  chainWebpack: () => {},

   /* 
    configureWebpack是调整webpack配置最简单的一种方式,可以新增也可以覆盖cli中的配置。
    可以是一个对象:被 webpack-merge 合并到webpack 的设置中去
    也可以是一个函数:如果你需要基于环境有条件地配置行为,就可以进行一些逻辑处理,可以直接修改或
新增配置,(该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。
    在函数内,你可以直接修改配置,或者返回一个将会被合并的对象。
  */
   configureWebpack: {}
    
  
}

下面进入正题,配置import 和 require 等路径别名。

webpack中是通过 resolve.alias 来实现此功能的,参考链接 https://www.webpackjs.com/configuration/resolve/

在vue-cli3.x中我们可以通过以下几种方式实现:

1.直接修改 cli-service  文件加下webpack的相关配置

  参考文章开头第一张图片的路径打开 base.js 文件,修改下图红框中的代码:

可以直接修改或者通过set方法继续添加想要的alias 配置。当然项目中不推荐使用这种方式,特别是与其他小伙伴相互协作的项目。

2.在vue.config.js 中使用 chainWebpack 方法,参考如下代码:

const path = require('path');
function resolve (dir) {
  //此处使用path.resolve 或path.join 可自行调整
  return path.join(__dirname, dir)
}
module.exports = {
  devServer: {
   ...
  },
  lintOnSave: false, // eslint-loader 是否在保存的时候检查
  productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
  filenameHashing: true, //文件hash
  chainWebpack: config => {
    config.resolve.alias
      // key,value自行定义,比如.set('@assets', resolve('src/assets'))
      .set(key,value)
  }
}

3.在vue.config.js 中使用 configureWebpack方法

  •  对象形式,此处的设置会和cli中的设置合并到一块
const path = require('path');
function resolve (dir) {
  return path.join(__dirname, dir)
}
module.exports = {
  devServer: {
     ...
  },
  lintOnSave: false, // eslint-loader 是否在保存的时候检查
  productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
  filenameHashing: true, //文件hash
  configureWebpack: {
    resolve: {
      alias: {
        '@assets': resolve('src/assets')
      }
    }
  },
} 
  •  函数形式
const path = require('path');
function resolve (dir) {
  return path.join(__dirname, dir)
}
module.exports = {
  devServer: {
     ...
  },
  // eslint-loader 是否在保存的时候检查
  lintOnSave: false, 
  // 生产环境是否生成 sourceMap 文件
  productionSourceMap: false,
  //文件hash
  filenameHashing: true, 
  configureWebpack: config => {
     if (isProduction) {
         ...
     } else {
       ...
     };   
    //直接修改配置
     config.resolve.alias['@asset'] = resolve('src/assets')
  }
} 

或者:

const path = require('path');
function resolve (dir) {
  return path.join(__dirname, dir)
}
module.exports = {
  devServer: {
     ...
  },
  // eslint-loader 是否在保存的时候检查
  lintOnSave: false, 
  // 生产环境是否生成 sourceMap 文件
  productionSourceMap: false,
  //文件hash
  filenameHashing: true, 
  configureWebpack: config => {
     if (isProduction) {
         ...
     } else {
       ...
     };   
    //返回一个将要合并的对象
     return {
       resolve: {
         alias: {
          '@asset':resolve('src/assets')
         }
       }
     }  
  }
} 

关于资料的一些坑:

在网上搜这个问题的时候,有很多答案是下面这个

const path = require('path');
function resolve (dir) {
  return path.join(__dirname, dir)
}
module.exports = {
  ...

  configureWebpack: config => {
     if (isProduction) {
         ...
     } else {
       ...
     };   
      
    Object.assign(config, {
        resolve: {
           alias: {
                    '@': resolve('./src'),
                    '@assets': resolve('./src/assets')
                  }
         }
     });
    
  }

   ...
} 

这种在逻辑上是没有问题的,但是采用这个方法在运行的自己项目的时候,总是提示有很多模块无法找到,后来在明白了上面cli-service里面的代码之后,终于找到了原因,因为Object.assign方法在合并对象时,如果目标对象(config)上有相同的属性(resolve),被合并的对象将会覆盖掉目标对象上的属性,所以运行完Object.assign()这段代码后,webpack的resolve这个属性值就变成了

 alias: {
         '@': resolve('./src'),
         '@assets': resolve('./src/assets')
  }

      而cli-service中设置的 resolve的其他属性值(下图红框中的extensions,modules)将会消失。

     cli-service中 设置resolve的代码如下:

      

      而我们知道 extensions: [ '.mjs', '.js', '.jsx', '.vue', '.json', '.wasm' ] },这个属性是设置哪些扩展名可以省略的,比如引入 'xx.vue'文件的时候,只需要写'xx'就行了,这个属性消失后,项目中通过省略扩展名引入文件时,就会无法解析省略扩展名的文件路径,造成文件无法找到的问题,进而导致编译项目时出错中断。

如果要使用这种方式可以 写成Object.assign(config.resolve,{alisa:{}});

以上就是对vue-cli3.x 构建项目中配置路径别名的总结。 

 

 

Logo

前往低代码交流专区

更多推荐