I'm trying to add the correct pdf loader to my nuxt.config.js file but nothing seems to be working so far. This is what I have in my build config, I'm pretty sure I need to add another rule to get pdf working but is not happening.
extend(config, ctx) {
// Run ESLint on save
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: "pre",
test: /\.(js|vue)$/,
loader: "eslint-loader",
exclude: /(node_modules)/,
});
}
},
},
I had the same issue with my downloadable pdf files and solved it by moving the download's folder to the static directory.
You are able to archive this by extending the build config in the nuxt.config.js.
module.exports = {
build: {
extend(config) {
// Find the rule which contains a assets file extension
const assetsLoader = config.module.rules.find(rule => rule.test.test('.png'));
// Overwrite the test regex and add `pdf`
assetsLoader.test = /\.(png|jpe?g|gif|svg|webp|pdf)$/i;
return config;
},
},
};
One of the ways to resolve it is by loading the instance of jspdf in the client-side.
if(process.client) {
const jsPDF = require('jspdf');
require('jspdf-autotable');
let doc = new jsPDF();
// ...your code
}
As per the Nuxt Documentation, check this out Window Document Undefined.
Related
I have just created a new CRA app. In our organization we have a micro frontend framework which has certain requirements when it comes to the the asset file of each micro frontend app. CRA will by default, create a asset-manifest.json file.
https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js#L656
Now I need to change this file to assets.json and make some structural changes as well. To achieve this I use CRACO and add the WebpackManifestPlugin.
const ManifestPlugin = require('webpack-manifest-plugin');
module.exports = {
webpack: {
plugins: {
// tried removing CRA definition for ManifestPlugin.
// It worked, but had no impact on my problem
// remove: ['ManifestPlugin'],
add: [
new ManifestPlugin({
fileName: 'assets.json',
generate: (seed, files, entrypoints) => {
const js = [],
css = [];
files.forEach((file) => {
if (file.path.endsWith('.js') && file.isInitial) {
js.push({ value: file.path, type: 'entry' });
}
if (file.path.endsWith('.css') && file.isInitial) {
css.push({ value: file.path, type: 'entry' });
}
});
return { js, css };
},
})
]
}
}
};
Whenever I build the application, my new assets.json file is generated as expected.
However, I can't get CRA, or webpack-dev-server I assume, to serve this file while I run my CRA app in development mode. It only resolves to the index.html file. I have looked through CRA source code and can't really find any relevant place where asset-manifest.json is mentioned.
So how do I get webpack-dev-server to serve my assets.json file?
You need to add the ManifestPlugin to webpack.plugins.remove array to receive only the configuration from WebpackManifestPlugin:
...
webpack: {
alias: {},
plugins: {
add: [
new WebpackManifestPlugin(webpackManifestConfig)
],
remove: [
"ManifestPlugin"
],
},
configure: (webpackConfig, { env, paths }) => { return webpackConfig; }
},
...
I am trying to add storybook to my project, which written using pug. Unfortunately, storybook stops to compile if I create story with component on pug. If I change template lang to html (and template itself), all works just fine.
I had this same issue last night when adding storybook to an existing Vue/Pug project.
Storybook supports extending it's webpack config.
First open the file .storybook/main.js in your project directory.
Here you can add a function for webpackFinal to the object, which received the webpack config as an argument, and u can push additional loaders into the rules.
More info here in the storybook docs:
https://storybook.js.org/docs/vue/configure/webpack
Here is my file where i have added pug and sass support:
const path = require('path');
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
],
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Make whatever fine-grained changes you need
config.module.rules.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
});
config.module.rules.push(
{
test: /\.pug$/,
use: [
{ loader: 'pug-plain-loader' }
]
}
);
// Return the altered config
return config;
},
}
I have Vue.js project I've setup previously that dynamically adds defined .scss files to my .vue template files, so I can access my variables, mixins, etc. in the templates without #importing them, or having them duplicate code from imports.
My problem is I'm setting up a NativeScript/Vue.js project with vue-cli-plugin-nativescript-vue and was curious if anyone has successfully setup their webpack to allow the same functionality. It's my understanding that the plugin replaces webpack with the latest when you run, as specified in the docs https://cli.vuejs.org/guide/webpack.html#replacing-loaders-of-a-rule.
Below is my vue.config.js (which compiles with no error) but doesn't seem to be working. I'm probably missing something or don't understand exactly how this is working, any help is appreciated.
const path = require('path')
module.exports = {
chainWebpack: config => {
const ofs = ['vue-modules', 'vue', 'normal-modules', 'normal']
const cssRules = config.module.rule('css')
const postRules = config.module.rule('postcss')
const addSassResourcesLoader = (rules, type) => {
rules
.oneOf(type)
.use('sass-resoureces-loader')
.loader('sass-resources-loader')
.options({
resources: './src/styles/_global.scss', // your resource file or patterns
})
}
ofs.forEach(type => {
addSassResourcesLoader(cssRules, type)
addSassResourcesLoader(postRules, type)
})
return config
},
}
Vue CLI provides a config to augment your CSS loaders:
// vue.config.js
module.exports = {
css: {
loaderOptions: {
scss: {
// sass-loader#^8.0.0
prependData: `import "~#/styles/_global.scss";`,
// sass-loader#^9.0.0 or newer
additionalData: `import "~#/styles/_global.scss";`,
}
}
}
}
I'm trying to use some dynamic styling in my Vue.JS application. The idea is to build SCSS themes to static CSS and use it as in my template to switch themes.
Since I'm using bulma as css framework all my styles look the same as:
theme-1.scss
$primary: wheat;
#import 'bulma/bulma';
The current solution is just a bootstrapped vue application with default webpack config. The only time I was able to build scss to css and use it further was the following config:
const path = require('path');
module.exports = {
mode: 'development',
entry: {
functions: [
'./src/index.js',
'./src/scss/theme1.scss',
'./src/scss/theme2.scss'
],
},
output: {
path: path.resolve(__dirname, 'src'),
filename: 'dist/js/[name].js',
},
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: 'dist/css/[name].css',
}
},
{
loader: 'sass-loader'
}
]
}
]
},
};
Unfortunately I can't use multiple entries in vue app. And it also seems to me is not the right way to work with single page application
Since i'm absolutely new to webpack and vue-loader I think that I do everything wrong and think in the wrong way. Maybe some plugin exists which do definitely the same thing as I want to?
Here is the solution for this issue:
in my vue.config.js I made the following:
module.exports = {
chainWebpack: config => {
config.entry('theme') // you can add here as much themes as you want
.add('./src/theme.scss')
.end();
},
css: {
extract: {
filename: '[name].css', // to have a name related to a theme
chunkFilename: 'css/[name].css'
},
modules: false,
sourceMap: true
},
}
I've typically not used file-loader in my CSS setup; instead I've always used a style-loader, css-loader with MiniCSSExtractPlugin:
https://github.com/webpack-contrib/mini-css-extract-plugin#advanced-configuration-example
Give that setup configuration for MiniCSSExtractPlugin a review.
MiniCSSExtractPlugin is a nice to have, so the most important thing to note is that you are missing the css-loader (which should be used instead of file-loader).
After building my website with Vue.js 2.6.2 using vue-cli, I encountered a problem with static resources (images in this case). Webpack bundles them up in the /img/ folder which is fine, but the images are given hashes like image_demo.25d62d92.png which is causing issues when trying to access those resources from an external source e.g. from another website.
There is an option for webpack to disable filenameHashing altogether, but that too great a sacrifice to not have the cache control for all the orher images on the website.
The desired solution is the option to have only some hand picked resources with their default names without the extra hash, while the other resources get the default hash for cache control.
Yes, there is a way. You will need to override the 'images' rule that vue-cli comes with.
vue inspect --rule images yields the following:
$ vue inspect --rule images
/* config.module.rule('images') */
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
}
}
]
}
(Protip: vue inspect is a useful tool for figuring out why things behave like they do when building with vue-cli)
All images
vue-cli recommends webpack-chain for 'advanced' configuration. I'm personally not a fan, but if you want to remove hashes for all images, you should probably modify the 'images' rule. Edit vue.config.js like so:
module.exports = {
// ...
chainWebpack: (config) => {
config.module
.rule("images")
.use("url-loader")
.loader("url-loader")
.tap((options) => {
options.fallback.options.name = "img/[name].[ext]"
return options
})
}
// ...
}
Specific images
In my case I wanted to remove hashes only for a specific group of images with a unique prefix, so I added the following to configureWebpack in vue.config.js:
module.exports = {
// ...
configureWebpack: {
module: {
rules: [
{
test: /unique-prefix-\d*\.png/, // <= modify this to suit your needs
use: [
{
loader: "url-loader",
options: {
limit: 4096,
fallback: {
loader: "file-loader",
options: {
name: "img/[name].[ext]", // <= note how the hash is removed
},
},
},
},
],
},
],
},
// ...
}
It could probably be done with webpack-chain as well, but I prefer the more vanilla Webpack config format.