How do i exclude a directory with mocking files from webpack build with vue.config.js? - vue.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!

Related

Embed react-native-web app into existing website

I want to embed a react-native-web application into an existing website and am currently looking for options how to do so.
The application should be a quite simple questionnaire which needs to be embedded into a website created with Elementor. My idea was to use the Elementor HTML widget and insert my application somehow, but unfortunately I cannot figure out how to do this.
I've got a bit of experience developing React Native(RN) apps but I am pretty new to web development and therefore thought it would be easier for me to go with RN and the react-native-web library.
So far, I've created a RN project using npx react-native init WebApp, copied the App.js, index.js and package.json files from react-native-web CodeSandbox template, deleted the node_modules folders and ran npm install. Then I was able to start and build this example web app with the scripts from the package.json.
Now my question, how can I use the output from the build directory and embed it into an html tag?
I also tried to use webpack with the configuration from the react-native-web docs to bundle the app but I always got a new error as soon as I fixed the last one. Is it possible to bundle a RN app into a single JS file which I could then insert into the website?
Looking forward to any advice!
Marco
I solved it by using the below webpack config. The created bundle.web.js' content is put into a script tag (<script>...</script>). This can be embedded into the HTML widget.
// web/webpack.config.js
const path = require('path');
const webpack = require('webpack');
const appDirectory = path.resolve(__dirname, '');
// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
test: /\.js$/,
// Add every directory that needs to be compiled by Babel during the build.
include: [
path.resolve(appDirectory, 'index.web.js'),
path.resolve(appDirectory, 'src'),
path.resolve(appDirectory, 'node_modules/react-native-uncompiled'),
],
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
// The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
presets: ['module:metro-react-native-babel-preset'],
// Re-write paths to import only the modules needed by the app
plugins: ['react-native-web'],
},
},
};
// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
},
},
};
module.exports = {
entry: [
// load any web API polyfills
// path.resolve(appDirectory, 'polyfills-web.js'),
// your web-specific entry file
path.resolve(appDirectory, 'src/index.js'),
],
// configures where the build ends up
output: {
filename: 'bundle.web.js',
path: path.resolve(appDirectory, 'dist'),
},
// ...the rest of your config
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
resolve: {
// This will only alias the exact import "react-native"
alias: {
'react-native$': 'react-native-web',
},
// If you're working on a multi-platform React Native app, web-specific
// module implementations should be written in files using the extension
// `.web.js`.
extensions: ['.web.js', '.js'],
},
};

No CSS files when running 'vue-cli-service build --watch'

I have a simple project generated with vue-cli. When I run the vue-cli-service build command it produces CSS file correctly. When I run the vue-cli-service build --watch command it only builds JavaScript files. There are no CSS files.
How can I generate CSS files in watch mode?
You can achieve this by adding this line of code in your vue.config.js
//vue.config.js
module.exports = {
//adding extract css true solves this issue
css: {
extract: true
}
}
https://cli.vuejs.org/config/#css-extract
There is a good chance that you have to use an extract plugin for webpack.
I know that in my vue.config.js file I'm using :
chainWebpack: config => {
if (config.plugins.has('extract-css')) {
const extractCSSPlugin = config.plugin('extract-css');
extractCSSPlugin &&
extractCSSPlugin.tap(() => [
{
filename: 'build.css',
chunkFilename: 'build.css'
}
]);
}
}
Hopefully this help you. However vue inject your css in watch mode right at the top of your file for automatic re-rendering purpose I think.

VueJS build started throwing Error: Conflict: Multiple assets emit to the same filename

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.

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'
}
}
});

Vue-cli 3.x watch and compile scss-files

I've a folder some scss-files under src/assets/scss and I want to accomplish, that my src/assets/scss/main.scss is watched and compiled during npm run serve and npm run build.
The compiled file should be placed in public or in dist, I don't know what the better solution is. I've tried to add an output-directory to my vue.config.js but nothing worked.
This is my current vue.config.js:
module.exports = {
css: {
loaderOptions: {
sass: {
data: '#import "#/assets/scss/main.scss";',
outputDir: './public/css/main.css'
}
}
}
}
The styles from main.scss will not be loaded in a vue-component. These styles will be loaded globally for the whole website.