VueJS build started throwing Error: Conflict: Multiple assets emit to the same filename - vue.js

My app used to work fine until I updated VueJS this morning. Now when I build, it shows the following error:
Error: Conflict: Multiple assets emit to the same filename img/default-contractor-logo.0346290f.svg
There's only one file like this in the repo.
Here's my vue.config.js:
module.exports = {
baseUrl: '/my/',
outputDir: 'dist/my',
css: {
loaderOptions: {
sass: {
data: `
#import "#/scss/_variables.scss";
#import "#/scss/_mixins.scss";
#import "#/scss/_fonts.scss";
`
}
}
},
devServer: {
disableHostCheck: true
}
};
I tried webpack fixes recommended in similar cases, but non helped.

I had the same error when importing SVG files using dynamically generated path in the require statement:
const url = require("../assets/svg/#{value}");
<img src={{url}} />
In this case file-loader processes all SVG files and saves them to the output path. My file-loader options were:
{
loader: "file-loader",
options: { name: "[name].[ext]" }
}
The folders structure has duplicate file names, something like this:
assets
|__ one
|____ file.svg
|__ two
|____ file.svg
In this case file-loader saves both file.svg files to the same output file: build/assets/file.svg - hence the warning.
I managed to fix it by adding [path] to the name option:
{
loader: "file-loader",
options: { name: "[path][name].[ext]" }
}

The answer by #ischenkodv is definitely correct, but because of my inexperience with webpack, I needed a little more context to use the information to fix the problem.
For the benefit of anyone else in the same situation, I'm adding the following details which I hope will be useful.
This section of the Vue.js documentation was particularly helpul:
VueJS - Modifying Options of a Loader
For the TL;DR fix, here is the relevant chunk of my vue.config.js:
// vue.config.js
module.exports = {
// ---snip---
chainWebpack: config =>
{
config.module
.rule('svg')
.test(/\.svg$/)
.use('file-loader')
.tap(options =>
{
return { name: "[path][name].[ext]" };
});
}
// ---snip---
};
In my project it was the flag-icon-css NPM package that was causing the Multiple assets emit to the same filename conflict errors. The above update to the vue.config.js file resolved the problem for me.
I suspect that the regular expression in the test could be tightened up to target just the items in the flag-icon-css package rather than matching all SVG files, but I haven't bothered since it's not causing any adverse effects so far.

Related

How do i exclude a directory with mocking files from webpack build with vue.config.js?

I have a directory called mock at root which contains mocking data that I use to run the app in development mode. I would like to exclude them when i build for production. I notice that it is being added into bundle whenever i run vue-cli-service build and it is bloating my app bundle size.
I am using vue-cli and so I have to work with vue.config.js.
It is not clear from the docs or any answers on the wider web how I can specify which folders/files to exclude from the build.
Here is a snippet of my vue.config.js.
module.exports = {
chainWebpack: (config) => {
config.resolve.symlinks(false)
},
configureWebpack: {
plugins: [
new CompressionPlugin()
]
},
css: {
loaderOptions: {
scss: {
prependData: `#import "#/styles/main.scss";`
}
}
}
}
This is not the perfect solution, but...
If you want to exclude that directory at build time, you can try to use require instead of import. Something like this (source):
if (process.env.VUE_APP_MY_CONDITION) {
require('./conditional-file.js');
}
But be aware of this!

How can I activate the sourcemap for Vue-Cli 4?

I believed the npm run serve command use the sourcemap by default for the js, but it seems not because I always see vue.runtime.esm.js:619.
I made a vue.config.js file at the root level project.
I try two things:
module.exports = {
configureWebpack: config => {
config.devtool = 'source-map'
}
}
and:
module.exports = {
configureWebpack: {
devtool: 'source-map'
}
}
None of them works. I still stuck with vue.runtime.esm.js:619 which is useless.
Does anyone know how really activate the source-map with vue-cli 4?
Using the generated vue.config.js from vue-cli v4 (generating a vue 3 project) It provided me this file:
// vue.config.js
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
})
I then modified it to this:
// vue.config.js
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
devtool: 'source-map',
}
})
Which works enough for me to enable VSCode debugging in Chrome/Electron.
*Edit
The error you are getting may be unrelated to source-maps and related to warnings from vue itself.
For example
runtime-core.esm-bundler.js:6584
[Vue warn]: Failed to resolve component: AMadeUpComponentName
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
at <MyView onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > >
at <RouterView>
at <App>
Unfortunately this is a limitation of vue. However, improvements have been made between VueJS v2 and v3. Finally, I couldn't find an original source, but I read that improving the warning messages to track down the cause of warnings and errors is a high priority feature.
* Edit 10/12/2022
I had an older project that this answer didn't solve at all. After a yarn upgrade and #vue/cli upgrading, this configuration began working again!
You are looking for the ProjectOptions chainWebpack property.
chainWebpack?: (config: ChainableWebpackConfig) => void;
Try the following in your vue.config.js file:
/** #type import('#vue/cli-service').ProjectOptions */
module.exports = {
// https://github.com/neutrinojs/webpack-chain/tree/v4#getting-started
chainWebpack(config) {
config.devtool('source-map')
},
}

Giving static filenames for build files in vue-cli3

I am using vue-cli3, when i build using npm run build -- --mode=production, it gives 2 css files and 2 js files.
Everytime i make a code change the name of the file also changes like app.de90cdf7.js and chunk-vendors.a9204242.js.
Is there a way in vue-cli to hardcode the files names as app.js and chunk-vendors.js ?
I'm little late to the party. We can chain webpack to apply name changes.
Using version #vue/cli 5.0.4 in year 2022
const { defineConfig } = require("#vue/cli-service");
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack : (config) => {
config.output.filename('[name].js');
},
css: {
extract: {
filename: '[name].css',
chunkFilename: '[name].css'
}
}
});

how to override vue cli-service entry settings

I'm trying to integrate a vue project that I built with the vue cli into an existing .net app. I'm very new to vue, so I'm trying to follow guides and such, but am left with lots of questions.
While trying to compile this, I found that the vue cli-service node module has the following for setting the main.js file located in it's base.js file.
webpackConfig
.mode('development')
.context(api.service.context)
.entry('app')
.add('./src/main.js')
.end()
.output
.path(api.resolve(options.outputDir))
.filename(isLegacyBundle ? '[name]-legacy.js' : '[name].js')
.publicPath(options.publicPath)
I need to override this since my .net app doesn't have a src directory and the usage of this vue app won't follow that path structure. I'm not seeing a way to do it in my vue.config.js file. I would expect that if I can override it, that would be the spot.
I could overwrite the base.js file where this exists, but when a co-worker runs npm install, they would get the default value rather than what I have. The only option I see there is checking in all the node modules to git which we really don't want to do.
For anyone in a similar situation, I found what worked for me. It's not the ideal solution due to the fact that it forces you to build into a js folder. That resulted in the file being put in Scripts\build\vue\js. Would be nice to be able to just dump it in the vue folder, but at least this works. Code below.
vue.config.js
module.exports = {
publicPath : "/",
outputDir: "Scripts/build/vue", //where to put the files
// Modify Webpack config
// https://cli.vuejs.org/config/#chainwebpack
chainWebpack: config => {
// Not naming bundle 'app'
config.entryPoints.delete('app'); //removes what base.js added
},
// Overriding webpack config
configureWebpack: {
// Naming bundle 'bundleName'
entry: {
quote: './Scripts/Quote/index.js' //where to get the main vue app js file
},
optimization: {
splitChunks: false
}
},
filenameHashing: false,
pages: {
quoteApp: { //by using pages, it allowed me to name the output file quoteApp.js
entry: './Scripts/Quote/index.js',
filename: 'index.html'
}
}
}

Changing file path of js and css files in production build

I need some assistance or at least to be pointed in the right direction. I am attempting to deploy a vuejs app using Vue CLI 3. When I run the build command the files are built into the dist folder, which works fine. There is also a js and css folder inside dist that contain the respective files. In my index.html is created the paths as /css/app.css or /js/app.js. I want the files to just be placed in the dist folder along with index.html and the paths to read simply app.css or app.js. My goal is to remove the /css/.
I am assuming this is accomplished in the vue.config.js by configuring webpack. I can’t seem to figure this out. I understand the baseURL setting but I can figure this part out..any help would be appreciated.
Thanks
it's answered here
https://github.com/vuejs/vue-cli/issues/1967
basically config should look like this
module.exports = {
chainWebpack: (config) => {
config.module
.rule('images')
.use('url-loader')
.tap(options => Object.assign({}, options, {
name: '[name].[ext]'
}));
},
css: {
extract: {
filename: '[name].css',
chunkFilename: '[name].css',
},
},
configureWebpack: {
output: {
filename: '[name].js',
chunkFilename: '[name].js',
}
}
};