-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Absolute path for assets in development mode, allowing correct paths when app is added to legacy website #2394
Comments
Look like the |
@underfin yea that works for production (I'm already using it), but I need it to work in development. The only way I can think of is to check whether it's dev or prod in the code itself, and generating the url's based on that. But I was hoping to find a less verbose approach. package.json: ...
"dev": "vite --base=http://localhost:3000/ --force",
... vite.config.js export default ({ command }) =>
defineConfig({
resolve: {
alias: [
{
find: '@',
replacement: resolve(__dirname, 'src'),
},
],
},
build: {
target: command === 'serve' ? 'esnext' : 'es2015',
minify: command === 'serve' ? false : 'terser',
outDir: '../../dist/vue/sidebar-vue3/',
emptyOutDir: true,
rollupOptions: {
input: {
sidebar: resolve(__dirname, 'index.html'),
},
output: {
entryFileNames: `assets/[name].${pkg.version}.js`,
chunkFileNames: `assets/[name].${pkg.version}.js`,
assetFileNames: `assets/[name].${pkg.version}.[ext]`,
}
},
},
plugins: [
vue(),
WindiCSS({
preflight: {
includeBase: false,
},
}),
htmlPlugin(command),
],
}); Would writing a rollup plugin that prepend base to urls with enforce: pre option work? Any pointers for how to solve this would be greatly appreciated. |
Wrote a quick plugin to test, and it worked :-) absolutify-paths.ts import { Plugin, } from 'vite';
import { CustomPluginOptions } from 'rollup';
export const absolutifyPaths = (options: CustomPluginOptions = {}): Plugin => {
const { strings = [], enforce = 'pre', apply = 'serve' } = options;
return {
name: 'absolutify-paths',
enforce: enforce,
apply: apply,
transform: (code: string, id: string) => {
let transformedCode = code;
strings.forEach((str) => {
if (code.includes(str[0])) {
transformedCode = transformedCode.split(str[0]).join(str[1]);
}
});
return {
code: transformedCode,
map: null
};
},
};
};
vite.config.js import { absolutifyPaths } from 'absolutify-paths';
absolutifyPaths({
strings: [
['url(/src', 'url(http://localhost:3000/src/'],
['url(\'/src/', 'url(\'http://localhost:3000/src/'],
['src="/src/', 'src="http://localhost:3000/src/'],
['\'/src/', '\'http://localhost:3000/src/'],
]
}), Update! I've updated the code above as the previous replace function didn't work on all searched strings. Also added some more examples in the strings option |
Related: #1539 |
Based on the conversation in #1539 it seems possibly like a feature to leave out, but let me leave my $0.02 explaining 2 use cases where I'm trying to work around it: Chrome Extensions and Electron (well, I'm using something similar not Electron per-se) apps are two examples where this would be beneficial, as there isn't another webserver running and the relative base URL may not be accurate. Current goodness:
Making
HTML references not working is an acceptable compromise IMHO. FWIW, setting |
Workaround plugin: {
enforce: 'pre',
apply: 'serve',
transform: (code, id) => {
return {
code: code.replace(/\/src\/(.*)\.(svg|png)/, 'https://webpack.livestorm.local/src/$1.$2'),
map: null,
}
},
} |
Thanks @Akryum! Awesome! Finally a solution that doesn't require me to manually patch vite. Referencing some of the issues I came accros that can benefit from this more or less: I ended up having to add {
enforce: 'pre',
apply: 'serve',
transform: (code, id) => {
return {
code: code
.replace(
/\/src\/(.*)\.(svg|jpg|png|webp)/,
'http://localhost:3000/src/$1.$2'
)
.replace(
/\/@fs\/(.*)\.(svg|jpg|png|webp)/,
'http://localhost:3000/@fs/$1.$2'
),
map: null
};
}
} Also, @daaku is right #2394 (comment), there are many non-standard web environments where you are not in control of the protocol or server that has the HTML page, thus you require all your assets to be prefixed with a base path (including in development). |
I, too, would like to see this implemented, as it'd address: #2196 ...which remains a point of contention for using Vite with any server-rendered CMS or hybrid setup. |
Would also love to see this addressed in some form. For me, #2394 (comment) works a treat for now. |
Using the technique described here to create a plugin to handle this works great... if the CSS rules are in a If the rules, however are in an e.g.: With this in .has-background {
background-image: url('/src/pills.jpg');
}
The plugin processes it. However if instead I have this in @import './pages/homepage.css'; ...and this inside of .has-background {
background-image: url('/src/pills.jpg');
} ...then the URL is not rewritten (though the CSS rule is included as expected). Am I missing something here in terms of what I'd need to do in order to get this to work with PostCSS To clarify, I am using this plugin code: {
name: 'asset-fixer',
enforce: 'pre',
apply: 'serve',
transform: (code, id) => {
return {
code: code.replace(/\/src\/(.*)\.(svg|jp?g|png|webp)/, 'http://localhost:3000/src/$1.$2'),
map: null,
}
},
}, from @Akryum that works great otherwise (thanks for that) |
Final version I'm using: {
enforce: 'pre',
apply: 'serve',
transform: (code, id) => {
code = code.replace(/(from '|import\(')(\/src|~?@)\/(.*)\.(svg|png|mp3|mp4)/g, '$1https://webpack.livestorm.local/src/$3.$4?import=')
code = code.replace(/(?<!local)(\/src|~?@)\/(.*)\.(svg|png|mp3|mp4)/g, 'https://webpack.livestorm.local/src/$2.$3')
return {
code,
map: null,
}
},
} Change |
ah, I have it sorted. I needed to change Here's what is working for me: {
name: 'static-asset-fixer',
enforce: 'post',
apply: 'serve',
transform: (code, id) => {
return {
code: code.replace(/\/src\/(.*)\.(svg|jp?g|png|webp)/g, 'http://localhost:3000/src/$1.$2'),
map: null,
}
},
}, Also updated article: https://nystudio107.com/blog/using-vite-js-next-generation-frontend-tooling-with-craft-cms#vite-processed-assets |
@khalwat That doesn't seem to cover all the cases for me. |
@Akryum which cases is it not covering for you? |
I didn't check but I tried it and it didn't work, some urls were not patched |
BTW you'll want to add the |
Newer version of the plugin: {
name: 'asset-base-url',
enforce: 'post',
transform: (code, id) => {
code = code.replace(/(from |import\()("|'|`)(\/src|~?@|\/@fs\/@)\/(.*?)\.(svg|png|mp3|mp4)/g, '$1$2https://webpack.livestorm.local/src/$4.$5?import=')
code = code.replace(/(?<!local)(\/src|~?@|\/@fs\/@)\/(.*?)\.(svg|png|mp3|mp4)/g, 'https://webpack.livestorm.local/src/$2.$3')
return {
code,
map: null,
}
},
} |
Is your feature request related to a problem? Please describe.
Need image paths to be absolute in order to preview vue app running on legacy website.
Legacy website example:
Describe the solution you'd like
A way to enable absolute paths when running dev so that it's possible to work and preview the vue app directly on the legacy website. Alternatively, add a how-to to the docs as I've seen people requesting something similar.
Describe alternatives you've considered
I've tried to find a way to rewrite urls via vue() vite plugin, server.proxy or rollup rewrite plugin which works for builds but not for development.
The text was updated successfully, but these errors were encountered: