第一步:定制静态资源根目录
这一步是Vue工程配置的基本操作,在Vue CLI官方文档讲的很明确了,在vue.config.js中配置assetsdir属性即可。
未设置或设置为默认值assetsdir: '',生成的目录是这样的:

指定明确的目录,即生成相对于publicPath的路径,如assetsdir: './assets'或者assetsdir: 'assets',生成的目录是这样的:

这样使得目录结构更清晰明了。
第二步:区分静态资源与动态生成的资源
如果在工程中已经提供了一部分全局静态资源,如normalize.css,为保持目录的统一可能也放置在public/assets/css目录下,这样,在最终的编译输出中,文件可能被大量的chunk-文件淹没。

这样我们需要给输出的文件单独设置子目录,于是可以设置css的extract属性,在开发环境时,我们可以直接设置为true以启用css文件的抽离,在生产环境则可以直接指定生成的chunkFile的目录。
css: {
extract: process.env.NODE_ENV === 'development' || {
chunkFilename: 'assets/css/chunk/[name]-[hash].css',
},
},
运行编译我们可以得到这样的目录结构

第三步:踩坑
如果在源码中存在相对路径的引用,编译过程将会自动进行处理,如字体、图片等,通过查询Vue CLI的源码,发现其是采用filename的值来计算相对路径的深度的。而filename默认路径为./assets/css/file.css,因此第二步中我们设定chunkFilename多了一层目录chunk,导致资源路径引用出现404错误。所以filename与chunkFilename可以不在同一目录,但一定要保持相同的层级深度。
// use relative publicPath in extracted CSS based on extract location
const cssPublicPath = process.env.VUE_CLI_BUILD_TARGET === 'lib'
// in lib mode, CSS is extracted to dist root.
? './'
: '../'.repeat(
extractOptions.filename
.replace(/^\.[\/\\]/, '')
.split(/[\/\\]/g)
.length - 1
)
css: {
extract: process.env.NODE_ENV === 'development' || {
// filename必须与chunkFilename层级一致,\node_modules\@vue\cli-service\lib\config\css.js 42行
filename: `assets/css/[name]/[name]-[hash].css`,
chunkFilename: 'assets/css/chunk/[name]-[hash].css',
},
},
第三步:js文件的编译输出
js文件的编译输出则比较灵活一些,在configureWebpack方法中可以进行更多的操作,也没有filename与chunkFilename路径绑定的问题,此处给出简单的示例。
configureWebpack () {
let config = {
plugins: [],
}
if (process.env.NODE_ENV === 'production') {
config.output = {
filename: (chunkData) {
// 通过chunkData可以根据chunkData.chunk.name进行更多区分
return `[name]/[name]-${hash}.js`
},
chunkFilename: `assets/js/chunk/[id]-[hash].js`,
}
}
// 一些其他的插件设置
// 最终返回配置
return config
}