Webpack hooks with multiple OS - webpack-4

Our development team is on both Windows and Linux. I have created a webpack 4 plugin using compiler hooks that works only on Linux machines. Is there a way to detect OS so I can write an alternate version for the Windows folks?
plugins: [
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap("AfterEmitPlugin", () => {
exec("sh generate-templates.sh src/main/resources/public/js", (err, stdout, stderr) => {
if (stdout) process.stdout.write(stdout);
if (stderr) process.stderr.write(stderr);
});
});
},
},
],

Write the plugin in Node.js instead of shell and there shouldn't be an issue with OS compatibility.
plugins: [
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap("AfterEmitPlugin", () => {
...use node here.
});
},
},
],

Related

Gatsby Build Error on Netlify - page-data.json failed paged “/”

when I try to build a gatsby app on netlify, I'm having this error that is generated by a 3rd party module called react-water-wave.
This is the error
I've already implemented a null loader on gatsby-node.js:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html" || stage === "develop-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /react-water-wave/,
use: loaders.null(),
},
],
},
})
}
}
This is how is coded the gatsby-plugin-emotion on gatsby-config.js
plugins: [
{resolve: `gatsby-plugin-emotion`,
options: {
// Accepts the following options, all of which are defined by `#emotion/babel-plugin` plugin.
// The values for each key in this example are the defaults the plugin uses.
sourceMap: true,
autoLabel: "always",
labelFormat: `[local]`,
cssPropOptimization: true,
}
}]
react-water-wave seems to be discontinued, the last commit is from 3 years ago and it has been reported with some incompatibilities during SSR and React version as it is inferred from https://github.com/homerchen19/react-water-wave/issues/14 and https://github.com/homerchen19/react-water-wave/issues/27.
It seems to don't work with React versions greater than 17.
That said, try playing (downgrading) with React-core versions (which can potentially lead to other errors) or try finding another alternative.

Replicate netplan nameserver configuration for centos

First of a warning: I'm a junior level with little experience using centos.
I'm running a puppet environment with a few different machines some example modules I'm running is consul and puppet-dns for the ubuntu machines I have used netplan to configure up my dns clients.
Dns Server machine
include dns::server
# Forwarders
dns::server::options { '/etc/bind/named.conf.options':
dnssec_enable => false,
dnssec_validation => no,
forwarders => [ 'IP1' ],
}
dns::zone { 'consul':
zone_type => forward,
forward_policy => only,
allow_forwarder => [ '127.0.0.1 port 8600' ],
}
DNS Client setup
/^(Debian|Ubuntu)$/: {
class { 'netplan':
config_file => '/etc/netplan/50-cloud-init.yaml',
ethernets => {
'ens3' => {
'dhcp4' => true,
'nameservers' => {
'search' => ['node.consul'],
'addresses' => [ "$dir_ip" ],
}
}
},
netplan_apply => true,
}
In order to replicate this on Centos7, I came accross ifcfg files
(/etc/sysconfig/network-scripts/ifcfg-ens3) however, I am not sure how to replicate the result from above within one of this files. Does anyone have experience with this ?
After some reading, I decided to edit /etc/resolv.conf with the help of puppetmod: saz-resolv_conf
class { 'resolv_conf':
nameservers => ["$dir_ip"],
searchpath => ['node.consul'],
}
I was a bit skeptical about this at first since the file had automated items from OpenStack, however, everything is working as expected.

How to access Vuejs methods to test with Jest?

I have the following file: deposit-form.js.
With the following code:
new Vue({
el: '#app',
data: {
title: 'title',
depositForm: {
chosenMethod: 'online',
payMethods: [
{ text: 'Already paid via Venmo', value: 'venmo' },
{ text: 'Pay online', value: 'online' },
{ text: 'In-person payment', value: 'person' }
],
},
},
methods: {
submitDeposit: function() {
$.ajax({
url: 'http://localhost:8000/api/v1/deposit/',
type:'post',
data: $('#deposit-form').serialize(),
success: function() {
$('#content').fadeOut('slow', function() {
// Animation complete.
$('#msg-success').addClass('d-block');
});
},
error: function(e) {
console.log(e.responseText);
},
});
},
showFileName: function(event) {
var fileData = event.target.files[0];
var fileName = fileData.name;
$('#file-name').text('selected file: ' + fileName);
},
},
});
I'm having problems on how to setup Jest, how to import the VueJs functions inside 'methods' to make the tests with Jest.
How should be my code on the deposit-form.test.js ?
The first thing you need to do is export Vue app instance.
// deposit-form.js
import Vue from 'vue/dist/vue.common';
export default new Vue({
el: '#app',
data: {...},
...
});
Now you can use this code in your spec file. But now you need to have #app element before running tests. This can be done using the jest setup file. I will explain why it's needed. When you import your main file (deposit-form.js) into a test, an instance of Vue is created in your main file with new. Vue is trying to mount the application into #app element. But this element is not in your DOM. That is why you need to add this element just before running the tests.
In this file you also can import jQuery globally to use it in your tests without import separately.
// jest-env.js
import $ from 'jquery';
global.$ = $;
global.jQuery = $;
const mainAppElement = document.createElement('div');
mainAppElement.id = 'app';
document.body.appendChild(mainAppElement);
Jest setup file must be specified in the jest configuration section in package.json.
// package.json
{
...,
"dependencies": {
"jquery": "^3.3.1",
"vue": "^2.6.7"
},
"devDependencies": {
"#babel/core": "^7.0.0",
"#babel/plugin-transform-modules-commonjs": "^7.2.0",
"#babel/preset-env": "^7.3.4",
"#vue/test-utils": "^1.0.0-beta.29",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.1.0",
"babel-loader": "^8.0.5",
"babel-preset-vue": "^2.0.2",
"jest": "^24.1.0",
"vue-jest": "^3.0.3",
"vue-template-compiler": "^2.6.7",
"webpack": "^4.29.5",
"webpack-cli": "^3.2.3"
},
"scripts": {
"test": "./node_modules/.bin/jest --passWithNoTests",
"dev": "webpack --mode development --module-bind js=babel-loader",
"build": "webpack --mode production --module-bind js=babel-loader"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"setupFiles": [
"<rootDir>/jest-env.js"
]
}
}
Also, you probably need to configure Babel to use the features of ES6 in your projects and tests. This is not necessary if you follow the commonjs-style in your code. Basic .babelrc file contains next code:
// .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "entry",
"targets": {
"browsers": [
"last 2 versions"
]
}
}
],
"vue",
],
"plugins": [
"#babel/plugin-transform-modules-commonjs",
]
}
Now you can write your tests.
// deposit-form.test.js
import App from './deposit-form';
describe('Vue test sample.', () => {
afterEach(() => {
const mainElement = document.getElementById('app');
if (mainElement) {
mainElement.innerHTML = '';
}
});
it('Should mount to DOM.', () => {
// Next line is bad practice =)
expect(App._isMounted).toBeTruthy();
// You have access to your methods
App.submitDeposit();
});
});
My recommendation is to learn Vue Test Utils Guides and start to divide your code into components. With the current approach, you lose all the power of components and the ability to test vue-applications.
I updated my answer a bit. As I understood from the comment to the answer, you connect the libraries on the page as separate files. Here is my mistake. I didn't ask if the build system is being used. Code in my examples is written in the ECMA-2015 standard. But, unfortunately, browsers do not fully support it. You need an transpiler that converts our files into a format that is understandable for browsers. It sounds hard. But it's not a problem. I updated the contents of the file package.json in response. Now it only remains to create an input file for the assembly and run the assembly itself.
The input file is simple.
// index.js
import './deposit-form';
The build is started with the following commands from terminal.
# for development mode
$ yarn run dev
# or
$ npm run dev
# for production mode
$ yarn run build
# or
$ npm run build
The output file will be placed in the directory ./dist/. Now instead of separate files you need to connect only one. It contains all the necessary for the library and your code.
I used webpack to build. More information about it can be found in the documentation. Good example you can find in this article.

Error of 'appendchild' of null during running ng test in angular 6

I have an angular 6 project with typescript 2.8.0 and node version 11.
I have a functional dev application and trying to setup a unit testing environment with jasmine karma, due to limited knowledge about these frameworks I am not able to debug the following error.
ERROR: TypeError: Cannot read property 'appendChild' of null
TypeError: Cannot read property 'appendChild' of null
at HtmlReporter.specDone (http://localhost:9876/base/node_modules/karma-jasmine-html-reporter/src/lib/html.jasmine.reporter.js?a380599bba71e79ed6dc82aa9a857815d894cfda:150:15)
at dispatch (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:4560:28)
at ReportDispatcher.specDone (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:4531:11)
at Spec.specResultCallback [as resultCallback] (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:1249:18)
at complete (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:567:12)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:421:1)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:188:1)
at drainMicroTaskQueue (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:595:1)
I have commented every spec in all the spec files, but still the following error resulted. But my mere concern is that the error is due to some incorrect configuration in karma.conf.ts
The following is my karme.config.ts file, please suggest me the correction to the environment ready.
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
environment: 'dev'
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
Edit:
The following is one of my spec files, and it has only one spec which is commented. So there are no spec methods that are running.
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { PassbackComponent } from './passback.component';
describe('PassbackComponent', () => {
let component: PassbackComponent;
let fixture: ComponentFixture<PassbackComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PassbackComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PassbackComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// it('should create', () => {
// expect(component).toBeTruthy();
// });
});
There are a lot of similar questions in StackOverflow but none of them solves because others are of incorrect specs but mine if of possibly some other reason
Thank you so much in advance.
Setup
Angular 7.* (CLI)
Karma 4.*
Fix
remove "kjhtml" from reporters
karma.config.js
...
reporters: ['progress', 'kjhtml']
...
I had the same problem and compared it to a working project. I fixed it by rolling back my version of karma. In my package.json I changed
"karma": "^3.1.3",
to
"karma": "~3.0.0",
I believe that there was an update to Karma which had broken something else - if I can find the conversation around it, I'll post it for additional information.

ng2-translate fails on iOS device when trying to set language with NetworkError (DOM Exception 19): A network error occurred

I have been trying to figure out why Globalization.getPreferredLanguage() would fail only when running on an iOS device (not when running on a simulator or Android device / emulator)
Globalization.getPreferredLanguage().then((property) => {
let lang = property.value;
if (lang) {
if (lang.startsWith('en')){
this.translate.use('en_GB');
}
else if (lang.startsWith('fr')) {
this.translate.use('fr_FR');
}
else {
this.translate.use('en_GB');
}
} else {
console.log("property.value is null");
}
}).catch((reason) => {
this.translate.use('en_GB');// <-- not only does this NOT WORK, but the reason given is NetworkError (DOM Exception 19): A network error occurred.
});
What I have tried:
Removing and adding the Globalization plugin with both ionic and cordova instructions:
ionic plugin rm cordova-plugin-globalization && ionic plugin add
cordova-plugin-globalization
sudo cordova plugin rm cordova-plugin-globalization && sudo cordova plugin add cordova-plugin-globalization
EDIT 1
So after more debugging I can see it is the angular ng2-translate 'use' function that is failing. In my app.module.ts:
import { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate/ng2-translate';
...
export function createTranslateLoader(http: Http) {
return new TranslateStaticLoader(http, '/assets/i18n', '.json');
}
...
#NgModule({
declarations: [
...
],
imports: [
...
BrowserModule,
HttpModule,
TranslateModule.forRoot({
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}),
...
]
...
})
export class AppModule { }
But in my app.component.ts when I call
this.translate.use('en_GB');
It throws some exception. I have checked and the files do exist in the folder:
/.../platforms/ios/www/assets/i18n
For me, Globalization.getPreferredLanguage() is never resolved. So I am currently using
this.deviceLang = navigator.language;
This returns the device language with its variant like (FR-FR / EN-US)