vue-cli
vue-cli copied to clipboard
"Avoid modifying webpack output.publicPath directly", but some usecases might need it. E.g. serving static from different domain?
Version
@vue/cli-service 3.5.0
Environment info
System:
OS: Linux 4.19 Ubuntu 20.04.2 LTS (Focal Fossa)
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Binaries:
Node: 12.22.1 - /usr/bin/node
Yarn: 1.17.3 - /mnt/c/Program Files (x86)/Yarn/bin/yarn
npm: 7.11.1 - /usr/bin/npm
Browsers:
Chrome: Not Found
Firefox: Not Found
npmPackages:
@fortawesome/vue-fontawesome: ^0.1.8 => 0.1.10
@vue/babel-helper-vue-jsx-merge-props: 1.2.1
@vue/babel-plugin-transform-vue-jsx: 1.2.1
@vue/babel-preset-app: 3.12.1
@vue/babel-preset-jsx: 1.2.4
@vue/babel-sugar-composition-api-inject-h: 1.2.1
@vue/babel-sugar-composition-api-render-instance: 1.2.4
@vue/babel-sugar-functional-vue: 1.2.2
@vue/babel-sugar-inject-h: 1.2.2
@vue/babel-sugar-v-model: 1.2.3
@vue/babel-sugar-v-on: 1.2.3
@vue/cli-overlay: 3.12.1
@vue/cli-plugin-babel: ^3.5.0 => 3.12.1
@vue/cli-plugin-eslint: ^3.5.0 => 3.12.1
@vue/cli-plugin-pwa: ^4.5.10 => 4.5.13
@vue/cli-service: ^3.5.0 => 3.12.1
@vue/cli-shared-utils: 3.12.1 (4.5.13)
@vue/component-compiler-utils: 3.2.0
@vue/eslint-config-airbnb: ^4.0.0 => 4.0.1
@vue/eslint-config-prettier: ^4.0.1 => 4.0.1
@vue/eslint-config-standard: ^4.0.0 => 4.0.0
@vue/preload-webpack-plugin: 1.1.2
@vue/web-component-wrapper: 1.3.0
emoji-mart-vue-fast: ^8.0.3 => 8.0.3
eslint-plugin-vue: ^5.0.0 => 5.2.3 (4.7.1)
vue: ^2.6.6 => 2.6.12
vue-affix: ^0.5.2 => 0.5.2
vue-avatar-editor-improved: ^1.0.4 => 1.0.7
vue-blurhash: ^0.1.4 => 0.1.4
vue-carousel: ^0.18.0 => 0.18.0
vue-cli-plugin-webpack-bundle-analyzer: ^2.0.0 => 2.0.0
vue-cli-webpack: 1.0.0
vue-click-outside: ^1.0.7 => 1.1.0
vue-ctk-date-time-picker: ^2.4.0 => 2.5.0
vue-custom-scrollbar: ^1.1.0 => 1.4.0
vue-debounce: ^2.3.0 => 2.6.0
vue-eslint-parser: 5.0.0 (2.0.3)
vue-hot-reload-api: 2.3.4
vue-loader: 15.9.7
vue-observe-visibility: 0.4.6
vue-resize: 0.4.5
vue-router: ^3.0.1 => 3.5.1
vue-slicksort: ^1.1.3 => 1.2.0
vue-smooth-dnd: ^0.8.1 => 0.8.1
vue-style-loader: 4.1.3
vue-template-compiler: ^2.5.21 => 2.6.12
vue-template-es2015-compiler: 1.9.1
vue-virtual-scroller: ^1.0.0-rc.2 => 1.0.10
vuejs-datepicker: ^1.6.2 => 1.6.2
vuex: ^3.0.1 => 3.6.2
npmGlobalPackages:
@vue/cli: Not Found
Steps to reproduce
Define output.publicPath in vue.config.js
What is expected?
I need a way to pass output.publicPath without this exception message. My usecase:
I serve one same Vue SPA on hundreds and thouthands of subdomains:
https://sub1.mydomain.com/ https://sub2.mydomain.com/ https://sub3.mydomain.com/ https://sub4.mydomain.com/
etc. Like workpsaces in Slack.
Every time when new user joins service and creates new workpace on new subdomain, it does not hit a cache on CDN because URL is always different https://sub123.mydomain.com/js/app.js, https://sub124.mydomain.com/js/app.js.
So CDN bypasses the request to slower upstream and takes redundant place in caches store by storing same files on different urls.
To solve this, only one simple thing which I need to do is:
configureWebpack: {
output: {
publicPath: process.env.NODE_ENV === 'production'
? 'https://sub1.mydomain.com/' // just to show idea - we serve files for all from one domain
(+add CORS settings on serving end) so now the cache on CDN will not be separated and all new users will hit one cache when they load JS/CSS/fonts.
If I use native top-level publicPath option, some Vue runtime code creates a redirect and breaks a route by adding domain there, but I don't want redirect, I really want index.html to be served from https://sub2.mydomain.com/, I only need to change URLs of assets, not route of the application.
I had to destroy validateWebpackConfig.js in my CI build pipeline to solve this issue quickly, and after this, applications works perfectly:
ADD package-lock.json .
ADD package.json .
RUN npm ci
# ugly fix to prevent Avoid modifying webpack output.publicPath directly.
RUN echo "module.exports = function validateWebpackConfig () {}" > 'node_modules/@vue/cli-service/lib/util/validateWebpackConfig.js'
But it would be better if we can disable this "smart mode" and allow some flexibility, at least if we would have an option like allowOutputPublicPath :
if (!singleConfig.allowOutputPublicPath && target === 'app' && singleConfig.output.publicPath !== options.publicPath) {
// only then drop exception
Is there any better/faster ways to point all statics to be loaded from a different domain? This definitely not super popular case, but from time to time developers might need it.
What is actually happening?
Configuration Error: Avoid modifying webpack output.publicPath directly. Use the "publicPath" option instead
+1
Also, it could be useful for webpack5 output: { publicPath: 'auto' }
feature
+1
This is a must for any kind of embedding where a widget is not served from the same domain for instance. It messes with the routing otherwise.
背景: vueCli 3.30后,废弃baseURL ,统一使用publicPath,同时禁用了output.publicPath 问题:项目打包的静态资源JS+CSS,想配置CDN域名,和项目域名不同域名,怎么搞嘛。 之前是只配置publicPath即可。
html 我们是通过Nginx代理到的CDN域名 JS+CSS 直接配置CDN域名,没有代理的原因是想节省链路,直接享受CDN加速
"@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0", "@vue/cli-plugin-typescript": "~4.5.0", "@vue/cli-plugin-unit-mocha": "~4.5.0", "@vue/cli-plugin-vuex": "~4.5.0", "@vue/cli-service": "~4.5.0",
@sodatea 豪群哥,方便帮忙指点一下吗~
I think I found a fix for this.
First, use vue cli's publicPath
instead of webpack:
vue.config.js
module.exports = defineConfig({
publicPath: WEB_CDN_DOMAIN || '/',
...
Then, change your router history from createWebHistory(process.env.BASE_URL)
to createWebHistory('/')
Index.js
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory('/'),
routes: [...],
});
export default router;
I think I found a fix for this.
First, use vue cli's
publicPath
instead of webpack:vue.config.js
module.exports = defineConfig({ publicPath: WEB_CDN_DOMAIN || '/', ...
Then, change your router history from
createWebHistory(process.env.BASE_URL)
tocreateWebHistory('/')
Index.js
import { createRouter, createWebHistory } from 'vue-router'; const router = createRouter({ history: createWebHistory('/'), routes: [...], }); export default router;
This fix works for me, but somehow in my project the router var should be like this (changed from base: process.env.BASE_URL,
)
const router = new VueRouter({
mode: 'history',
base: '/',
routes
})
if you just want set webpack.output.publicPath
in vue-cli, you can use this plugin vuecli-publicpath-webpack-plugin