Ignore specific components and assets from being added to dist folder in Nuxt - vue.js

I have a multiplatform Nuxt 2.15 project with the following structure:
assets/platform1/... //contains fonts, images and config files
assets/platform2/...
components/platform1SpecificComponent.vue
components/platform2SpecificComponent.vue
components/sharedComponent.vue
layouts/platform1/...
layouts/platform2/...
components/platform1SpecificPage.vue
components/platform2SpecificPage.vue
components/sharedPage.vue
I've wrote the following plugin to dynamically register different platform's components unders the same name to be able to reuse most of my pages:
export default ({ store }) => {
const config = store.state.platform.config
Vue.component('NewsCard', () => import(`#/components/pages/news/${config.news.cardComponent.name}`))
}
The problem that after platform1 build, output dir contain assets from platform2 which increases size. At the same time sass or vue loader tries to parse style of vue template's part for components that are not used and not referenced in platform1, throwing errors about missing sass variables...
I know that nuxt allows to define ignore property in nuxt.config.json (or .nuxtignore) but that only works for pages and layouts...
I tried to configure webpack rules by modifiying nuxt.config.js extend property:
const fontsLoader = config.module.rules.find(i => String(i.test) === String('/\\.(woff2?|eot|ttf|otf)(\\?.*)?$/i'))
fontsLoader['exclude'] = new RegExp(`assets/(?!${platform})`)
and actually that removed fonts from dist folder but it started to throw warnings: that these files doent have appropriate webpack loader. The same behaviour I observed when tried to exclude specific vue components from vue-loader.
So doesnt seem like a good solution after all..
Becides, the same approach didnt work for images inside assets folder:
const imgLoader = config.module.rules.find(i => String(i.test) === String('/\\.(png|jpe?g|gif|svg|webp|avif)$/i'))
imgLoader['exclude'] = new RegExp(`assets/(?!${platform})`)
all the images are still added to dist...
Is there a way to tell nuxt (or webpack via nuxt config) to ignore specific folders with fonts and images under the /assets folder and specific vue components that are not pages or layouts?

Related

Nuxt Content: How to link to binary files from markdown/yaml?

I have a Nuxt Content project, which fetches a number of content files like so:
/content/resources/item.yaml
---
item:
title: Hello World
pdf: sample.pdf
Which is pulled into the Vue component:
async asyncData({ $content }) {
const resources = await $content('resources').fetch()
return { resources }
},
Where should the PDF file go in the Nuxt folder structure? and how should it be referred to in the YAML file? I'm trying something like:
/content/resources
-- item.yaml
-- sample.pdf
and then in Vue: <a :href="item.pdf" ..., which always just results in https://url/sample.pdf, which does not load obviously. What is the obvious thing I am missing, as I can't find it anywhere in the Nuxt Content docs?
/content/resources
-- item.yaml
/assets/files
-- sample.pdf
and referencing /assets/files/sample.pdf also doesn't work.
The Nuxt Content docs describe using static assets for this.
Move sample.pdf to static/ in the root of your Nuxt project (e.g., in static/sample.pdf), and then use its static-relative path in your pdf YAML property:
pdf: /sample.pdf

Embed script only on production with Vue CLI 3

My main goal is to inject a tag into my index.html only in production (it's a New Relic monitoring code snippet).
My Vue.js is built and served as a static resource, so using {% %} tags to surround the script block with a condition doesn't seem to work in this use case.
So I tried to add the New Relic code snippet on my Vue.js app using html-webpack-plugin, since I found a simple Webpack plugin using on html-webpack-plugin. It's a pretty simple plugin, it just create the node and pushes it in the page body : https://github.com/robrap/html-webpack-new-relic-plugin/blob/master/src/index.js#L25
I register the plugin by setting my vue.config.js this way (I first tried to add the script no matter the environment) :
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackNewRelicPlugin = require('#yodatech/html-webpack-new-relic-plugin');
module.exports = {
configureWebpack: {
plugins: [
new HtmlWebpackPlugin(),
new HtmlWebpackNewRelicPlugin({the plugin options})
]
}
}
The plugin actually does its job well (the code snippet is injected), but its execution messes up with Vue CLI default configuration.
Some stylesheets and scripts aren't referenced anymore in the final index.html file, the <div id=app></div> is not there anymore, the app is broken.
I don't know if using HtmlWebpackPlugin is a dead end, but I currently don't know any other way to reach my goal.
Has anyone an idea on how I could make this work ?
Thanks a lot to anyone passing by.
EDIT : The plugin I was trying to use seemed to be flawed, I had to modify it to make it work with Vue CLI. My main problem has been solved by the selected answer.
vue.config.js option configureWebpack just merges the options you provide to a webpack config provided by Vue CLI. So by using your code, you are running 2 distinct HtmlWebpackPlugins (one from your config and one default from Vue CLI)
Try this instead:
var HtmlWebpackNewRelicPlugin = require('#yodatech/html-webpack-new-relic-plugin');
module.exports = {
configureWebpack: {
plugins: [
new HtmlWebpackNewRelicPlugin({the plugin options})
]
}
}

Multiple Aurelia Instances - Aurelia Webpack Plugin - aureliaApp option - "module not found"

I am composing my web app as a number of Aurelia "feature" apps - although I'm not using Aurelia features as such. Consequently in my html markup I have two entry points pointing to different apps:
<!-- Top Navigation Bar -->
<div aurelia-app="topnav"></div>
<!-- Main App-->
<div aurelia-app="main"></div>
I am using webpack and everything works perfectly using the single "main" app. Webpack generates a JS file "main.bundle.js" which I include in the src tag.
Things are not so straightforward when I added the "topnav" app. In webpack I tell the plugin to use a different aureliaApp name:
new AureliaPlugin({ aureliaApp: "topnav"}),
and, as you can see my HTML entrypoint also calls "topnav". Webpack generates a JS file "topnav.bundle.js" which I also include. I have a file called "topnav.ts" which contains the aurelia Cionfigure function which ends:
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName("nav")));
And a pair of files "nav.ts", "nav.html" which constitute my viewmodel and view.
When I run the app aurelia loads and the "nav" module code executes. But I then get an error - see below.
The module which it reports that it cannot find is the one entered into the HTML markup.
Should this work? Have I missed something?
I should add, everything seems to work. I can create and update properties in the viewmodel and these are bound to the view. It's just that this error is thrown.
You are doing nothing wrong, just unsupported scenario. Per official doc-wiki: https://github.com/aurelia/webpack-plugin/wiki/AureliaPlugin-options#aureliaapp
You can have only 1 auto entry module with aureliaApp configuration. To solve this, you just need to add PLATFORM.moduleName('topnav') to your main.ts (and put it on root level)
Another way to do is to bootstrap manually:
// in your index.ts
import { bootstrap } from 'aurelia-bootstrapper';
// bootstrap top nav application, with one instance of Aurelia
bootstrap(aurelia => {
// do your configuration
aurelia
.start()
.then(() => aurelia.setRoot(
PLATFORM.moduleName('topnav'),
document.querySelector('#topnav')
);
});
// bootstrap main application, with another instance of Aurelia
bootstrap(aurelia => {
// aurelia.use.standardConfiguration();
// ...
aurelia
.start()
.then(() => aurelia.setRoot(
PLATFORM.moduleName('app'),
document.querySelector('app')
)
});

Is there a way to build a master css file based on required css in javascript components using browserify?

Let's say I have modules similar to this one:
"use strict";
var moduleCss = require("module1.css");
var template = require("module1.hmtl");
module.exports = function(){
//my module code here
};
And another one with a different css file.
"use strict";
var moduleCss = require("module2.css");
var template = require("module2.hmtl");
module.exports = function(){
//my module code here
};
The main file would look like this:
"use strict";
var module1 = require("module1");
var module2 = require("module2");
var normalize = require("normalize.css");
var bootstrap = require("bootstrap.css");
module.exports = function(){
//my module code here
};
Instead of appending each css file content as a style tag, i'd like to get a main.css when building the main bundle by looking at each required css file in each module and building a single CSS file containing all the styles in all required modules so that I can append this single css file where I want.
I'm basically trying to have the css requirements in the same spot as the js and html requirements. The solutions that I found so far require a different CSS file that keeps track of each module css dependency, so adding or removing a module in my applications requires work in 2 files, the main js and the main css.
Is there a way to achieve this? To have ALL dependencies into one file? Or could a "package.json" thingy be used for each module where the CSS dependencies could be declared?
After playing around a little bit with browserify it turned out the transform function hook reveals the file name of each required file. I basically looked for css and less file, return a empty module for them, and kept each file in a reference array.
After the bundle was done, by listening to the bundle event, I created a string where I basically "included" each file that I captured in the reference array.
With the import file created, I simply passed it to the less compiler.
Here's a link to the gist for my current task : https://gist.github.com/vladnicula/fd1ff7b30ef20789e1dc

sails.js less livereload with grunt watch not working

I got my less files compiled in css perfectly by grunt and I see result in .tmp/public/styles
So now livereload with grunt-contrib-watch should be made naturally in sails generated project ?
Or do I have to make a special configuration ?
I found that in tasks/pipeline.js file but not sure of what to do.
// CSS files to inject in order
//
// (if you're using LESS with the built-in default config, you'll want
// to change `assets/styles/importer.less` instead.)
var cssFilesToInject = [
'styles/**/*.css'
];
I saw in the file tasks/README.md :
###### `sails lift`
Runs the `default` task (`tasks/register/default.js`).
And in the file default.js we got :
module.exports = function (grunt) {
grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']);
};
But watch.js file is missing in the folder...
What should it be ?
Watch does only looking for files that have changed and execute less, sass, injection and so on - but it doesn't make a reload.
You can add this in task/config/watch.js