How to change filename inside a rule? (Vue CLI 5) - vue.js

I have this rule, using vue inspect
/* config.module.rule('svg') */
{
test: /\.(svg)(\?.*)?$/,
type: 'asset/resource',
generator: {
filename: 'img/[name][ext]'
}
},
I need to change filename for example to "[contenthash][ext]"
but I cannot do it using
module.exports = defineConfig({
chainWebpack: (config) => {
config.module.rule("svg").generator.filename = "[contenthash][ext]";
},
})
because I cannot set generator ,
I can rewrite all rules using
module.exports = defineConfig({
configureWebpack: (config) => {
config.module.rules = [
{
test: /\.(svg)(\?.*)?$/,
use: [
{
loader: "svg-inline-loader",
options: {
name: "[contenthash].[ext]",
},
},
],
},
];
},
})
but I need other rules to exist... so how can I change fileName of svg?

Try this:
chainWebpack: (config) => {
config.module.rule("svg")
.set('generator', {
filename: "[contenthash][ext]"
})
}
Source

Related

(vite or rollup) build exoprt name will be change

I want to try to use vite to package my component library, but I encounter a problem. After packaging, I will change the name of the variable exported from the file
this is vite.config.js:
import { defineConfig } from "vite";
import path from "path";
import { createVuePlugin } from "vite-plugin-vue2";
import pkg from "./package.json";
const inspector = require("inspector");
inspector.open("9292", "127.0.0.1");
const extensions = [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"];
export default (/** if you want to use mode : { mode }*/) =>
defineConfig({
mode: "production",
base: "./",
plugins: [createVuePlugin()],
resolve: {
extensions,
alias: [
{
find: `#gb/utils`,
replacement: path.resolve(__dirname, "../../packages/utils/src"),
},
],
},
css: {
modules: {
scopeBehaviour: "global",
},
preprocessorOptions: {
less: {
javascriptEnabled: true,
charset: false,
},
scss: {
charset: false,
},
},
},
build: {
lib: {
entry: path.resolve(__dirname, "src/index.js"),
name: "index",
formats: ["es"],
fileName: () => `index.js`,
},
cssCodeSplit: true,
outDir: "es",
assetsDir: "style",
watch: {},
minify: "minify",
rollupOptions: {
output: {
// preserveModules: true,
// preserveModulesRoot: "src",
// assetFileNames: ({ name }) => {
// const { ext, dir, base } = path.parse(name);
// console.log(ext, dir, base);
// if (ext !== ".css") return "[name].[ext]";
// return path.join(dir, "style", 'style.css');
// },
chunkFileNames: (chunkInfo) => {
// console.log(chunkInfo);
return "[name].js";
},
manualChunks: (id, { getModuleInfo, getModuleIds }) => {
const filePath = path.parse(id);
const dirPath = filePath.dir
.replace(/.*\/src/, "")
.replace("/", "");
if ([".css", ".scss", ".less"].includes(filePath.ext)) {
return `${dirPath}/style`;
}
if (/vue&type=template&lang/.test(filePath.name)) {
const realName = filePath.name.replace(
/\.vue\?vue\&type\=template\&lang/,
""
);
return `${dirPath}/${realName}`;
}
if (dirPath) {
return `${dirPath}/${filePath.name}`;
}
return `${filePath.name}`;
},
},
external: [
...Object.keys(pkg.devDependencies),
/#gb\/utils.*/,
/node_modules/,
],
},
},
});
this is my code:
export default function (fileUrl = '') {
let file = fileUrl.split('?')[0]
let fileName = file.substring(file.lastIndexOf('/') + 1) || ''
let suffixLastIndex = fileName.lastIndexOf('.')
let name = fileName.substring(0, suffixLastIndex)
let suffix = fileName.substring(suffixLastIndex + 1, fileName.length)
return {
name,
suffix
}
}
when i build, the export name will be a,b,c...z:
function getUrlToFileSuffix(fileUrl = "") {
let file = fileUrl.split("?")[0];
let fileName = file.substring(file.lastIndexOf("/") + 1) || "";
let suffixLastIndex = fileName.lastIndexOf(".");
let name = fileName.substring(0, suffixLastIndex);
let suffix = fileName.substring(suffixLastIndex + 1, fileName.length);
return {
name,
suffix
};
}
export { getUrlToFileSuffix as g };
I need correct name
some people know how to set config?
Thanks so much!
set output.minifyInternalExports = false

You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file using Webpack 5.40.0

I am building web version from existing React Native project using react-native-web.
webpack.config.js
const path = require('path');
const webpack = require('webpack'); const HtmlWebpackPlugin =
require('html-webpack-plugin');
const appDirectory = path.resolve(__dirname); const {presets} =
require(`${appDirectory}/babel.config.js`);
const compileNodeModules = [ // Add every react-native package that
needs compiling // 'react-native-gesture-handler', ].map(moduleName
=> path.resolve(appDirectory, `node_modules/${moduleName}`));
const babelLoaderConfiguration = { test: /\.js$|(tsx|jsx)?$/, //
Add every directory that needs to be compiled by Babel during the
build. include: [
path.resolve(__dirname, 'index.web.js'), // Entry to your application
path.resolve(__dirname, 'App.web.tsx'), // Change this to your main App file
path.resolve(__dirname, 'src'),
...compileNodeModules, ], use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets,
plugins: ['react-native-web'],
}, }, };
const svgLoaderConfiguration = { test: /\.svg$/, use: [
{
loader: '#svgr/webpack',
}, ], };
const imageLoaderConfiguration = { test: /\.(gif|jpe?g|png)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
}, }, };
module.exports = { entry: {
app: path.join(__dirname, 'index.web.js'), }, output: {
path: path.resolve(appDirectory, 'dist'),
publicPath: '/',
filename: 'fictionate.me.bundle.js', }, resolve: {
extensions: ['.web.tsx', '.web.ts', '.tsx', '.ts', '.web.js', '.js'],
alias: {
'react-native$': 'react-native-web',
}, }, module: {
rules: [
babelLoaderConfiguration,
imageLoaderConfiguration,
svgLoaderConfiguration,
], }, plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'index.html'),
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
// See: https://github.com/necolas/react-native-web/issues/349
__DEV__: JSON.stringify(true),
}), ], };
babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
};
When I am trying to build web, it failed with following issue.
enter image description here
Please help me if someone knows how to fix this issue.

Webpack optimise and compress CSS and Javascript based on production mode inside webpack.config.js

I have the following NPM scripts inside package.json:
"scripts": {
"start": "cross-env NODE_ENV=development webpack --mode development",
"build": "cross-env NODE_ENV=production webpack --mode production"
},
if I run npm run build (production mode) I want to add optimization (see below) to compress my CSS and Uglify the Javascript. How do I achieve that?
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
if I run npm start I want to watch the files and further the same as production mode except optimization. I am building a Drupal site so I need to build the assets also in development.
My webpack.config.js looks like this now:
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const config = {
entry: {
main: "./src/index.js",
courses: "./src/courses.js",
vendor: "./src/vendor.js"
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new MiniCssExtractPlugin({ filename: '[name].css' }),
new CopyPlugin([
{ from: './src/assets/images', to: 'assets/images' },
{ from: './src/assets/icons', to: 'assets/icons' }
]),
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './assets/fonts',
},
},
}
]
}
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
//...
}
if (argv.mode === 'production') {
//...
}
return config;
};
How do I build this in?
I fix it by adjusting webpack.config.js like below:
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const config = {
//Entry Point
entry: {
main: "./src/index.js",
courses: "./src/courses.js",
vendor: "./src/vendor.js"
},
//Output
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
//Watch
watch: false,
watchOptions: {
ignored: ['node_modules']
},
//Loader
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
]
},
{
//For fonts
test: /\.(woff|woff2|ttf|otf|eot)$/,
use: [
{
//using file-loader too
loader: "file-loader",
options: {
outputPath: "fonts"
}
}
]
}
]
},
//plugin
plugins: [
new MiniCssExtractPlugin({ filename: '[name].css' }),
new CopyPlugin([
{ from: './src/assets/images', to: 'assets/images' },
{ from: './src/assets/icons', to: 'assets/icons' }
]),
],
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
//...
config.mode = "development";
config.watch = true;
}
if (argv.mode === 'production') {
//...
config.mode = "production";
config.optimization = {
splitChunks: {
chunks: "all"
},
minimize: true,
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin({
cache: true
})
]
};
}
return config;
};
If anybody have improvements on above, please let me know.

How do I use stylus-resources-loader with Vue CLI 3?

I know that it involves modifying vue.config.js, but simply pasting my desired config in the configureWebpack object doesn't seem to work. Has anyone else been able to figure this out?
Desired config to add:
module: {
rules: [
{
test: /\.vue$/,
use: [
{
loader: "vue-loader",
options: {
loaders: {
stylus: [
{
loader: "stylus-resources-loader",
options: {
resources:
"./src/assets/_base.styl",
},
},
],
},
},
},
],
},
],
},
Thank you!
const path = require('path');
module.exports = {
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-loader')
.tap((options) => {
options.loaders.stylus = options.loaders.stylus.concat({
loader: 'stylus-resources-loader',
options: {
resources: path.resolve('./src/assets/_base.styl'),
},
});
return options;
});
},
};
UPDATE:
It should be noted that the value of the lang attribute in <style lang="stylus"> will affect the way the configuration item is written!
When lang is stylus, the stylus are mounted on loader, which should be written like this: options.loaders.stylus, and when the value of lang is styl, It should be written as options.loaders.styl.
Because of the following code in #vue/cli-service/lib/webpack/CSSLoaderResolver.js:
getLoader (test, loader, options = {}) {
styl (test = /\.styl$/) {
return this.getLoader(test, 'stylus')
}
stylus (test = /\.stylus$/) {
return this.getLoader(test, 'stylus')
}
}
refer to https://stackoverflow.com/a/49086022/4723163

webpack build css rules have different order then in development

I am not sure if this is a webpack issue, vue-loader for webpack issue or just something that I am doing wrong.
When I am running npm run build to build a distribution for my Vue.js application the CSS rules applied in the dist app are in different order then in my development environment thus my CSS overrides are different and app doesn't render right...
Here is demonstration for one element:
npm run dev - proper render
npm run build - improper render
UPDATE: added webpack config files
webpack.base.conf.js
var path = require('path')
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, '../dist/static'),
publicPath: '/static/',
filename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.vue'],
alias: {
'src': path.resolve(__dirname, '../src')
}
},
resolveLoader: {
root: path.join(__dirname, 'node_modules')
},
module: {
preLoaders: [
{
test: /\.vue$/,
loader: 'eslint',
exclude: /node_modules/
},
{
test: /\.js$/,
loader: 'eslint',
exclude: /node_modules/
}
],
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.scss$/,
loaders: ['style', 'css?sourceMap', 'sass?sourceMap']
},
{
test: /\.(png|jp?g|gif|svg|woff2?|eot|ttf)(\?.*)?$/,
loaders: [
'url?limit=20000&name=[name].[ext]?[hash:7]',
'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}'
]
},
{
test: /\.html$/,
loader: 'html'
}
]
},
eslint: {
formatter: require('eslint-friendly-formatter')
},
vue: {
loaders: {
sass: 'style!css!sass?indentedSyntax'
}
},
stylus: {
use: [require('nib')()],
import: ['~nib/lib/nib/index.styl']
}
}
webpack.dev.conf.js
var webpack = require('webpack')
var config = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
// eval-source-map is faster for development
config.devtool = '#eval-source-map'
// add hot-reload related code to entry chunks
var polyfill = 'eventsource-polyfill'
var devClient = './build/dev-client'
Object.keys(config.entry).forEach(function (name, i) {
var extras = i === 0 ? [polyfill, devClient] : [devClient]
config.entry[name] = extras.concat(config.entry[name])
})
// necessary for the html plugin to work properly
// when serving the html from in-memory
config.output.publicPath = '/'
config.plugins = (config.plugins || []).concat([
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
inject: true
})
])
module.exports = config
webpack.prod.conf.js
var webpack = require('webpack')
var config = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
// naming output files with hashes for better caching.
// dist/index.html will be auto-generated with correct URLs.
config.output.filename = '[name].[chunkhash].js'
config.output.chunkFilename = '[id].[chunkhash].js'
// whether to generate source map for production files.
// disabling this can speed up the build.
var SOURCE_MAP = true
config.devtool = SOURCE_MAP ? 'source-map' : false
// generate loader string to be used with extract text plugin
function generateExtractLoaders (loaders) {
return loaders.map(function (loader) {
return loader + '-loader' + (SOURCE_MAP ? '?sourceMap' : '')
}).join('!')
}
// http://vuejs.github.io/vue-loader/configurations/extract-css.html
var cssExtractLoaders = {
css: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css'])),
less: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'less'])),
sass: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'sass'])),
stylus: ExtractTextPlugin.extract('vue-style-loader', generateExtractLoaders(['css', 'stylus']))
}
config.vue = config.vue || {}
config.vue.loaders = config.vue.loaders || {}
Object.keys(cssExtractLoaders).forEach(function (key) {
config.vue.loaders[key] = cssExtractLoaders[key]
})
config.plugins = (config.plugins || []).concat([
// http://vuejs.github.io/vue-loader/workflow/production.html
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.optimize.OccurenceOrderPlugin(),
// extract css into its own file
new ExtractTextPlugin('[name].[contenthash].css'),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /src/index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: '../index.html',
template: 'src/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
})
])
module.exports = config
What helped me, was tapping into the html plugin config, by adding this to vue.config.js
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].chunksSortMode = function (chunk1, chunk2) {
const order = ['first', 'second', 'third']
const order1 = order.indexOf(chunk1.names[0])
const order2 = order.indexOf(chunk2.names[0])
return order1 - order2
}
return args
})
},