Webpack bundle analyzer shows that icons from bootstrap-vue package are 535kb in size.
I don`t want to use them in a project, so I have been trying to exclude the package with a webpack IgnorePlugin.
According to example in documentation, I have tried to write this:
new webpack.IgnorePlugin({
resourceRegExp: /^icons(.*)$/,
contextRegExp: /^bootstrap-vue(.*)$/
})
but it didn`t work. The only thing I was able to reproduce, is to completely exclude bootstrap-vue lib via this constriction new webpack.IgnorePlugin(/bootstrap-vue/)
So how I can exclude only icons?
Here is the way to ignore the icons from bootstrap-vue:
new webpack.IgnorePlugin({
resourceRegExp: /\/icons\//,
contextRegExp: /bootstrap-vue/,
});
Next time if you are in doubt try to use checkResource function instead, it's easier to write and understand in comparison to regexp:
new webpack.IgnorePlugin({
checkResource (resource, context) {
if (context.includes('bootstrap-vue')) {
console.log(resource, ':::', context)
// check console to figure out how the resource is used
// update the function until it's satisfies your case
// then move to regexp if you wish
}
return false
},
})
But after doing this research it turned out that some components actually use some icons and icons in general are not as big as I expected. Using source of the bootstrap-vue had bigger impact on our bundle. So decided to stick with this approach instead
Related
I am trying to add a new element class to each of my pagination bullet, and I want to retain the default style of the swiper. So what I did is
pagination={
clickable: true,
bulletClass: `swiper-pagination-bullet ${style['feature-pagination']}`,
}
I was able to get the style of swiper-pagination-bullet and my custom style. However, the other functionalities is not working anymore (e.g. click function, active selection)
I tried to check the code and it looks like the swiper is not currently handling multiple class, since this line of code returns empty since it is only expecting a single class only.
Is there any work around for this? I like to create pull request for this, but I like to ask the community of I am missing in here.
Update
Now it support multiple class with this changes. You can add multiple class by separating them with spaces
pagination={
clickable: true,
bulletClass: `swiper-pagination-bullet ${style['feature-pagination']}`,
}
Old
So I requested an enhancement to Swiper Repository. As of the moment, the pull request to handle bulletClass and bulletActiveClass still haven't accepted.
For the mean time, this is the best workaround for it.
pagination={
clickable: true,
bulletClass: `swiper-pagination-bullet`,
renderBullet: (index, className) => {
return `<span class="${className} feature-pagination"></span>`;
}
}
There's always an overlap with Navbar dropdown when more than one is clicked. It focuses and takes a few minutes to clear this becomes a problem because it causes clutter.
The configuration for this in the Vuepress docs is just to add navbar items and ariaLabel any know how I can stop this behaviour.
themeConfig: {
nav: [
{
text: 'Languages',
ariaLabel: 'Language Menu',
items: [
{ text: 'Chinese', link: '/language/chinese/' },
{ text: 'Japanese', link: '/language/japanese/' }
]
}
]
}
Here's an example
To answer your question one would need to address two distinct issues:
how do I run custom JavaSCript in VuePress?
how do I close any previously open dropdowns on click in my current VuePress theme, using JavaScript?
For the first problem there are several solutions (one of them being by using a custom component with code run in its mounted() hook, but this would require you to include that component in every page and make sure it doesn't run more than one time (since you want to bind events to elements).
I believe the cleanest way would be by adding a <script> to <head> which can be achieved by adding this to the head prop of your .vuepress/config.js export:
head: [
// ...existing stuff, if any,
['script', {}, `
(function() {
// your code here...
})();
`]
]
However, there are a few problems with the above solution. Firstly, it's going to be run as soon as it's parsed, and that's inside the <head> tag. Which means none of the contents of your page are rendered yet. And the second problem is you're in a template literal. You don't really want to be writing JavaScript code in a template literal. Ideally you should be able to put your code in a '.js' file and append it as a <script> tag.
In order to do that, you need to create a .vuepress/public/ folder, if you don't already have one. Place your .js file in there (I used test.js but feel free to name it as you like). Modify the above code to:
['script', {}, `
(function() {
var s = document.createElement('script');
s.src = './test.js';
var h = document.querySelector('head');
h.appendChild(s);
})();
`]
Change ./test.js to your file's name.
Now your file has clean JavaScript and the door is open. Your code executes in the window object context.
To answer the second part of your question, well..., it largely depends on the theme you are using. If you're using the default theme (which seems to be the case, from the SS you posted), this should work, if placed inside your .js file:
document.addEventListener('DOMContentLoaded', fixDropDowns);
function fixDropDowns() {
document.body.addEventListener('click', (ev) => {
const header = document.querySelector('header');
if (header) {
const dds = header.querySelectorAll('.dropdown-wrapper');
[...dds].forEach(el => el.classList.remove('open'));
const curr = ev.target.closest('.dropdown-wrapper');
if (curr) {
curr.classList.add('open');
}
}
})
}
But it's based on a close inspection of the generated markup.
Specifically on the fact the dropdowns have a class of .dropdown-wrapper and that they're opened by toggling class open on them. The above is just an example and will likely not work on other themes and might even stop working on the default theme in some future version.
When I use nuxt to develop my project, I find some problems.
window.__NUXT__=(function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,$,aa, ..... code was too larger
can I remove it or use js file to replace it?
I have found a relatively perfect solution. I will share it with you here. You can also take a look at the website I developed using NUXT Sample Website
The key is the hook function vue-renderer:ssr:context, you can set the context.nuxt = null to remove any data in window._NUXT_.
But it is not work well, you have to add serverRender and routePath to window.nuxt
// nuxt.config.js
{
...,
hooks: {
'vue-renderer:ssr:context'(context) {
const routePath = JSON.stringify(context.nuxt.routePath);
context.nuxt = {serverRendered: true, routePath};
}
}
}
You can see the result at my site
I want to have a gulp task in Visual Studio Code which watches all files in a folder called less with the extension .less. When found, a task must compile the less files to a folder called css on the same level as the less folder.
Current code:
gulp.task('less', function() {
gulp.src('less/*.less',{ cwd:'..' })
.pipe(less())
.pipe(gulp.dest( 'css' ), { cwd:'..' });
});
gulp.task('default', function() {
gulp.watch('./**/less/*.less', ['less']);
});
What I want:
x
y
less
style.less
css
style.css
What above code does:
x
y
less
style.less
css
y
less
style.css
I had this working when being specific in the path, but the problem is that i've less folders on multiple levels. How can I solve this?
I know this is bit old question, but felt worth sharing my answer.
gulp.task('app:less', [], function () {
return gulp.src(['./src/**/*.less'], { base: './src/' })
.pipe(less())
.pipe(gulp.dest('./src/'));
});
Setting base option to root folder with dest path to ./src/ worked for me.
Currently there is no way to do it. The only thing which could approach you to a solution is gulp-flatten. However, this requires to specify a fixed number of parents to include. In your case, where you have folders in different levels, you'd need to specify a different number for each case. So, the only option would be to modify the flatten code to support something like an excludeParents, which does the contrary that flatten, i.e exclude a fixed number of parents (in your case, 1).
Try this :
gulp.task('less', function() {
gulp.src(['**/*.less', *.less],{ cwd:'less' })
.pipe(less())
.pipe(gulp.dest('css'));
});
I saw there is somes questions related to mine (like this interesting one), but what I wonders is how to do it correctly, and I couldn't find it via the others questions or the RequireJS documentation.
I'm working on a quite heavy web application that will run in only one html page.
Before RequireJS, I used to do a lot of JS modules with public methods and connecting them via the on event on the Dom READY method, like this :
var DataList = function () {
this.base = arguments[0];
this.onUpdate = function (event) { ... }
}
$(function () {
var dataList = {}; DataList.apply(dataList, [$('#content')]);
$('table.main', dataList.base).on ('update', dataList.onUpdate);
});
With RequireJS, I can easily see that I can split DataList and all others classes like this on individual files, but what about the $(function () {}); part?
Can I still keep it this way, but instead of the DOM ready function of jQuery, I put the events on the main function() of the RequireJS, when my primary libs are loaded?
Or do I have to change the way I create JS "classes", to include a init function maybe, that will be called when I do a, for example :
require(['Datalist'], function(dataList) {
dataList.init($('#content'));
});
What annoys me the most is that since I have only one html file, I'm afraid the require() will have to load a huge list of files, I'd prefer it to load just libs that, them, would load sub libs required to work.
I don't know, the way of thinking with RequireJS lost me a bit :/
How would you do?
"Can I still keep it this way, but instead of the DOM ready function of jQuery, I put the events on the main function() of the RequireJS, when my primary libs are loaded?"
If you separate the functions or 'classes' into modules then you can use the RequireJS domReady function:
require(['module1'], function(module1) {
domReady(function(){
// Some code here ftw
})
});
The benefit here is the domReady function will allow downloading of the modules instantly but won't execute them until your DOM is ready to go.
"Or do I have to change the way I create JS "classes", to include a init function maybe, that will be called when I do a, for example"
You won't need to change the way you interact with your code this way, but you can probably improve it. In your example I would make DataList a module:
define(function(require) {
var $ = require('jquery');
var DataList = function () {
this.base = arguments[0];
};
DataList.prototype.onUpdate = function() {
};
return DataList;
});
require(['data-list'], function(DataList) {
var data = {};
// Call DataList with new and you won't need to set the context with apply
// otherwise it can be used exactly as your example
new DataList(data);
});
"What annoys me the most is that since I have only one html file, I'm afraid the require() will have to load a huge list of files, I'd prefer it to load just libs that, them, would load sub libs required to work."
Make your code as modular as you want/can and then use the optimiser to package it into one JS file.