Include npm dependency in karma - npm

How can I include a dependency in package.json (not a devDependency) in karma?
I can include the file in node_modules/<dependency>, but I was looking for something more generic, including the main file.

I did not find any other better way to include them in karma.conf.js than
module.exports = function(config) {
var cfg = {
frameworks: ["jasmine", "commonjs"]
, files: [
{pattern: "node_modules/" + deps + "/*.js", included: true, watched: false}
, ...
]
...
};
cfg.preprocessors["node_modules/" + deps + "/**/*.js"] = ["commonjs"];
config.set(cfg);
};

Related

Webpack CopyPlugin : add file to plugin directory

I'd like to add the current module folder during my webpack compilation to my dist/ directory. For now, in /dist, I have something like that
const toCopy = [
'./../../../../node_modules/flatpickr/dist/flatpickr.min.js',
'./../../../../node_modules/flatpickr/dist/flatpickr.min.css',
]
this is the part of my webpack CopyPlugin
...
plugins: [
new CopyPlugin({
patterns: toCopy.map((entry) => {
console.log(entry);
return { from: entry }
})
})
]
And it gives me that
/dist
flatpickr.min.css
flatpickr.min.css
And I'd like that in order to avoid conflict if files from different modules have the same name .
for example, flatpickr as a ie.css, fr.js... but some other module could also have those files
/dist
/flatpickr
flatpickr.min.css
flatpickr.min.css
I've ended by created a loop over all my assets to copy to keep the CopyPlugin structure
const toCopy = new Map();
toCopy.set('popper', './../../contrib/bootstrap_sass/js/popper.min.js',);
toCopy.set('flatpickr', ['./../../../../node_modules/flatpickr/dist/flatpickr.min.js',
'./../../../../node_modules/flatpickr/dist/flatpickr.min.css']);
let toCopyFormatted = [];
for (let [dest, entries] of toCopy.entries()) {
if (typeof entries === 'string') {
let data = {to: dest}
data['from'] = entries;
toCopyFormatted.push(data);
} else {
entries.forEach(function (v, k) {
let data = {to: dest}
data['from'] = v;
toCopyFormatted.push(data);
})
}
}

Webpack - how to tell not compiling a js file for a specific entry point

Context
I am actually managing some dependencies via npm. Then I wrote a webpack.config.js to handle my imports :
Bundle Jquery + popper + Bootstrap.js
Bundle codemirror with my modules needs (xml autocomplete and so on)
...
Collect fonts from the fontawesome node_module
I am using django, so there is a collectstatic command which is helping me to collect all scripts, fonts, styles etc. to the folder I want. Everything is working great :
My bundled scripts are available
And for style sheets, I'm using relative imports to the 'vendor' node_module.
I am capable to get fonts to node_modules, and deliver it to the correct folder as expected.
Problem
I'm new to webpack world, and for sure I'm not using it as it should be, but it's working.
However when I run to compile my stuffs, an extra file is generated fontawesome.js in my fonts folder, is it possible to avoid this unexpected behavior.
What am I missing ?
It is not a big deal as long as I'm not importing this file, but I don't want to pollute my repo.
Edit
I updated the code of my webpack config.
Well, I figured out that the js file was generated from the filename in my entry point. But I don't want this file :)
wepback.config.js
"webpack": "^5.6.0",
var path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // Extract css in its own file
const webpack = require('webpack');
const path_modules = path.resolve(__dirname, 'node_modules');
const base_path = path.resolve(__dirname, 'src');
const dist_static = path.resolve(__dirname, 'webpacked_src');
module.exports = {
entry: {
bootstrap: {
import: [
base_path + '/bootstrap/bootstrap-bundle.js',
//base_path + '/bootstrap/test.scss'
],
filename: 'js_packed/[name].js',
},
fontawesome: {
import: [
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-brands-400.eot',
//path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-brands-400.svg',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-brands-400.ttf',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-brands-400.woff',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-regular-400.eot',
//path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-regular-400.svg',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-regular-400.ttf',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-regular-400.woff',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-regular-400.woff2',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-solid-900.eot',
//path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-solid-900.svg',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-solid-900.ttf',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-solid-900.woff',
path_modules + '/#fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2',
],
filename: 'fonts/[name].js'
},
codemirror: {
import: [
base_path + '/codemirror/code-mirror.js',
path_modules + '/codemirror/lib/codemirror.css',
path_modules + '/codemirror/theme/monokai.css', // Import the theme style --> Little selection midnight / material-darker / material-ocean / monokai (sublimetext)
path_modules + '/codemirror/addon/hint/show-hint.css',
],
filename: 'js_packed/[name].js',
},
vue: {
import: [
base_path + '/vue/vue.js',
],
filename: 'js_packed/[name].js',
},
},
output: {
path: dist_static
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
autoprefixer = require('autoprefixer'),
new MiniCssExtractPlugin({
filename: "css_packed/[name].css", // change this RELATIVE to the output.path
}),
],
module: {
rules: [
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, // instead of style-loader
'css-loader'
]
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{
loader: 'file-loader',
options: {outputPath: 'css/', name: '[name].min.css'}
},
'sass-loader'
]
}
],
},
};
fontawesome.js
And the content of the generated file, if it can help webpack experts :
(() => {
"use strict";
var t = {};
t.g = function () {
if ("object" == typeof globalThis) return globalThis;
try {
return this || new Function("return this")()
} catch (t) {
if ("object" == typeof window) return window
}
}(), (() => {
var r;
t.g.importScripts && (r = t.g.location + "");
var e = t.g.document;
if (!r && e && (e.currentScript && (r = e.currentScript.src), !r)) {
var p = e.getElementsByTagName("script");
p.length && (r = p[p.length - 1].src)
}
if (!r) throw new Error("Automatic publicPath is not supported in this browser");
r = r.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/"), t.p = r + "../"
})(), t.p, t.p, t.p, t.p, t.p, t.p, t.p, t.p, t.p, t.p, t.p, t.p
})();
Unfortunately, this is a bug in webpack: https://github.com/webpack/webpack/issues/11671
In the meantime, it's straight forward to add a custom webpack plugin that will remove these files. Here's what I'm using to delete all JS files (because I'm using a CSS file as my entry):
plugins: [
{
// Delete empty JS files; work around for https://github.com/webpack/webpack/issues/11671
apply: (compiler) => {
compiler.hooks.afterEmit.tap('DeleteJSFilesPlugin', (compilation) => {
const iter = compilation.emittedAssets.entries();
for (const [key] of iter) {
if (key.match(/.*\.js$/)) {
fs.unlinkSync(path.join(compilation.outputOptions.path, key));
}
}
});
}
}
]

Vue.js: Is it possible to do "Conditional compilation" with a Vue project?

In for example Swift/iOS development, it's possible to differentiate builds for different environments with "flags" such as:
#if STAGING
// one set of logic here
#endif
#if PRODUCTION
// another set of logic here
#endif
Is it possible to achieve the same with a Vue.js project, and how would we go about doing it? I am aware of makes different routes conditionally available for different roles (which is also quite neat), but I am optimally looking for the option to differentiate on a source code level.
Hope someone has some great insights! It could include:
How to exclude parts of a file (such as the #if STAGING above) from a build target
How to exclude entire files from a build target
etc.
you have the ability to use this syntax
if(process.env.NODE_ENV === 'production') {
console.log("this is the prod env!!!!!!!!!!");
config.output.path = path.resolve(__dirname, "dist");
}
make sure that when you run the script with the correct env's for each environment (local, dev, staging, prod etc ..) :D
just change the vue-loader output.
the source code
<template v-if="process.env.NODE_ENV === 'development'">
development only
</template>
default output
var render = function() {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c(
"div",
{ attrs: { id: "app" } },
[
_vm.process.env.NODE_ENV === "development"
? [_vm._v(" development only ")]
: _vm._e(),
_c("router-view")
],
2
)
}
just use regex to replace _vm.process.env. by process.env is ok.
// webpack.config.js
module: {
rules: [{
// must set post
enforce: 'post',
test: /\.vue$/,
use: [{
loader: './myLoader'
}]
}]
}
// myLoader.js
module.exports = function (source, map) {
if (source.indexOf('_vm.process.env') > -1) {
source = source.replace(/_vm.process.env/g, 'process.env')
}
this.callback(
null,
source,
map
)
}
Final the vue-loader result change
var render = function() {
var _vm = this
var _h = _vm.$createElement
var _c = _vm._self._c || _h
return _c(
"div",
{ attrs: { id: "app" } },
[
// change to true
true
? [_vm._v(" development only ")]
: undefined,
_c("router-view")
],
2
)
}

vue-cli linting throwing camelcase warning when the rule is disabled

I'm building an app with vue-cli, using airbnb rules to lint.
Despite me adding a rule to my .eslintrc.js config file, and the rule appying on other files, this particular variable in my Welcome.vue file keeps throwing a warning when linting.
The warning:
warning: Identifier 'tables_count' is not in camel case (camelcase) at src\components\Welcome.vue:49:33:
47 | enableAll: function enableAll() {
48 | const tables_count = this.tables.length;
49 | for (let i = 0; i < tables_count; i += 1) {
| ^
50 | this.tables[i].enabled = true;
51 | }
52 | },
The full .eslintrc.js file:
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/essential',
'#vue/airbnb',
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
indent: ['error', 4],
camelcase: ['warn', { properties: 'never' }],
},
parserOptions: {
parser: 'babel-eslint',
},
};
The strucure of my app is as follows:
App.vue
Welcome.vue
Game.vue
Both App.vue and Game.vue have variables with an under score and the linting is not throwing warnings for them.
App.vue: this.show_welcome = true;
Game.vue: this.current_answer = '';
What have I done wrong to make one particular Vue file offend the linter so much?!
This is either when I run npm run serve or npm run lint
NOTE: I thought I'd worked it out, but still no...
Currently I only have unit tests for welcome.vue, which has it's own lint file, but I've added the rule in there and I'm still getting the warnings:
tests/unit/eslintrc.js
module.exports = {
env: {
jest: true,
},
rules: {
camelcase: ['warn', { properties: 'never' }],
},
};
For a typescript project:
.eslintrc.js
{
rules: {
'#typescript-eslint/camelcase': 'off'
}
}
If you don't want eslint to check for variable casing then just turn it off with camelcase: 'off' in your .eslintrc.js.

How do I integrate PostCSS into Broccoli angular-cli Build?

It seems like this build script is running but the CSS that is output is not minified or auto prefixed. I am attempting to compile SASS, then run the output through Post CSS with Broccoli and the angular-cli. I figure maybe some ember-cli folks could help as well. What am I doing wrong?
The build outputs this in terminal:
Slowest Trees | Total
----------------------------------------------+---------------------
BroccoliTypeScriptCompiler | 1274ms
vendor | 502ms
PostcssFilter | 465ms
but the CSS is the same as if it were output from SASS, not Post CSS.
Here is my angular-cli-build.js:
'use strict';
/* global require, module */
const Angular2App = require('angular-cli/lib/broccoli/angular2-app');
const compileSass = require('broccoli-sass');
const compileCSS = require('broccoli-postcss');
const cssnext = require('postcss-cssnext');
const cssnano = require('cssnano');
const mergeTrees = require('broccoli-merge-trees');
const Funnel = require('broccoli-funnel');
const _ = require('lodash');
const glob = require('glob');
var options = {
plugins: [
{
module: cssnext,
options: {
browsers: ['> 1%'],
warnForDuplicates: false
}
},
{
module: cssnano,
options: {
safe: true,
sourcemap: true
}
}
]
};
module.exports = function(defaults) {
let sourceDir = 'src';
let appTree = new Angular2App(defaults, {
sourceDir: sourceDir,
sassCompiler: {
includePaths: [
'src/style'
]
},
vendorNpmFiles: [
'systemjs/dist/system-polyfills.js',
'systemjs/dist/system.src.js',
'zone.js/dist/*.js',
'es6-shim/es6-shim.js',
'reflect-metadata/*.js',
'reflect-metadata/*.js.map',
'rxjs/**/*.js',
'#angular/**/*.js',
'rxjs/**/*.js.map',
'#angular/**/*.js.map',
'd3/d3.js',
'three/build/three.js',
'three/examples/js/postprocessing/*.js',
'three/examples/js/shaders/*.js'
]
});
let sass = mergeTrees(_.map(glob.sync('src/**/*.scss'), function(sassFile) {
sassFile = sassFile.replace('src/', '');
return compileSass(['src'], sassFile, sassFile.replace(/.scss$/, '.css'));
}));
let css = compileCSS(sass, options);
return mergeTrees([sass, css, appTree], { overwrite: true });
};
It was the order of operations, my trees were not overwriting appTree!
This works!
return mergeTrees([appTree, sass, css], { overwrite: true });