Webpack, bundle loader and common chunk plugin issue - javascript

I have a page A.js and a page B.js and have base class base.js for it.
I import base.js for each A and B and use it as extend for class A and B.
My router loads those pages via require('bundle!pages' + url + '.js');
I would like to have base.js as a part of one common.js.
I added common chunk plugin to webpack
new webpack.optimize.CommonsChunkPlugin({
children: true,
name: 'common',
filename: 'common.js',
minChunks: 2,
})
but as an output I still have duplicated base.js in class a.js and b.js.
Is there any issue with bundle loader and common chunk plugin?
a.js
import Base from '../base';
class A extends Base {
constructor() {
super();
}
create() {}
}
export default A;
b.js
import Base from '../base';
class B extends Base {
constructor() {
super();
}
create() {}
}
export default B;
base.js
class Base {
constructor() {}
}
export default Base;
router.js
let loader = require('bundle!pages' + url + '.js');
loader((module) => callback(module.default));

Try this:
in webpack.config.js add to the exporting object this property
externals: { 'base': 'Base' }
and include this in your html header
I think that feature is from webpack 2

Related

Export class as a module in webpack

I'm using Webpack to import a javascript file that has a single class.
my_class.js
console.log('hello from my_class');
class myClass {
// ...
}
index.js
import './my_class.js';
webpack.config.js
const path = require('path')
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
}
I'm trying to use this class on a page.
index.html
<script src="./dist/bundle.js"></script>
<script>
const myClass = new myClass();
</script>
I am able to seem my console log ("hello from my_class") but myClass is showing up as undefined.
Uncaught ReferenceError: myClass is not defined
What do I need to do such that myClass is exported and available in the markup?
Firstly you should export the class.
export class myClass {
// ...
}
And for browsers you should use IIFE or UMD format:
output: {
library: 'someLibName',
libraryTarget: 'umd',
filename: 'bundle.js'
}
2021 and webpack thinks federated apps are higher priority than adding ES module support 🤷‍♂️ Use rollup if you don't want to use UMD.
And reference: someLibName.myClass
As you have not exported class from my_class.js file, you will not be able to import it.
console.log('hello from my_class');
class myClass {
// ...
}
export default myClass;
And your import should be like
import myClass from './my_class.js';

webpack es6 module not found

I am new to webpack, want to bundle my js classes
I am using es6 classes and linqjs.min, jquery-3.4.1.js and gsap.min
for starter I want only to bundle index.js and my class but I get an error
Module not found: cant resolve (myclass) in src directory
in my index.js for importing class:
import myClass from 'js/myClass'
and for exporting my class I used
export class myClass{ } and
module.export= myClass
my webpack.config.js is:
const HTMLWebPackPlugin = require ('html-webpack-plugin');
module.exports = {
module:{
rules:[
{
test: /\.js$/,
exclude:/node_modules/,
use:{
loader:"babel-loader"
}
},
{
test:/\.html$/,
use:[{
loader:"html-loader",
options:{minimize:true}
}]
}
]
},
plugins:[
new HTMLWebPackPlugin({
template:"./src/index.html",
filename: "./index.html"
})
]}
I don't understand my mistake how can I fix it. Thanks.
You are trying to do a default import, whereas you are doing a named export.
Either go with a default export, adding the default keyword:
export default class MyClass {}
along with
import MyClass from './js/MyClass.js';
Or, go with a named export / import:
export class MyClass {}
with
import { MyClass } from './js/MyClass.js';
Please note that by convention, class names start with a capital letter.
Medium has a good article on the difference: https://medium.com/#etherealm/named-export-vs-default-export-in-es6-affb483a0910

How to declare a JS mixin for vue?

I'm writting a vue project with typescript and I want to use a mixin from thrid-part library which write by javascript, how to write a .d.ts to make ts can find function define in the mixin?
I tried this way and it not working:
// common.d.ts
declare module 'thrid-part-lib' {
import { VueClass } from 'vue-class-component/lib/declarations';
export interface SomeMixin<T> extends VueClass<T> {
refresh(): Promise<void>;
}
}
// index.ts
import { Component, Mixins } from 'vue-property-decorator';
import { SomeMixin } from 'thrid-part-lib';
#Component
export default class Index extends Mixins(SomeMixin) {
public foo() {
this.refresh(); // 'refresh' is not define.
}
}
You can augment a third party mixin with creating a file like vuelidate-error-extractor.d.ts:
declare module 'vuelidate-error-extractor' {
import { ValidationRule } from 'vuelidate/lib/validators';
// eslint-disable-next-line #typescript-eslint/class-name-casing
export class singleErrorExtractorMixin extends Vue {
readonly events: any;
readonly name: string;
readonly isValid: boolean;
readonly hasErrors: boolean;
readonly preferredValidator: ValidationRule;
}
}
This augments this JS file, but in an incomplete manner.
This is documented in "Augmenting Types for Use with Plugins".
Put this in a .d.ts file in your project to add a refresh() mixin method to components:
// 1. Make sure to import 'vue' before declaring augmented types
import Vue from 'vue'
// 2. Specify a file with the types you want to augment
// Vue has the constructor type in types/vue.d.ts
declare module 'vue/types/vue' {
// 3. Declare augmentation for Vue
interface Vue {
refresh(): void;
}
}

Angular 7 karma test with importing external JS modules

I am testing a Angular 7 component which has importing JS modules like:
component.ts
import * as classA from '../../classA'; // Imported JS modules
export class component implements OnInit {
public a = new classA(10); // Instantiate
...
}
classA.js
class classA {
constructor (a) {
this.max = a;
...
}
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = classA;
}
component.spec.ts
import * as classA from '../../classA';
I am importing classA as what I did in component.ts.
Component.ts is working perfectly but when I am running ng test, it gives an error: TypeError: classA is not a constructor
I tried to include it in karma.conf.js like:
module.exports = function (config) {
config.set({
...
files: [
"../app/classA.js"
]
});
};
But still get same error. Anyone has any idea how to import JS modules in unit testing?
You use es6 modules import but define commonjs module.
Better use es6 modules as well.
classA.js
class classA {
constructor (a) {
this.max = a;
...
}
export default classA
Or use require:
let classA = require('../../classA');
I found the way to fix this testing error. In Angular 7, the right way to import JS commonjs module in component.ts is
import classA from '../../classA';
with
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
in tsconfig.json

#storybook/angular cannot load scss file on stories index

I have been trying to use storybook for my angular project and I use this guide https://storybook.js.org/basics/guide-angular/
I use the recommended config for webpack for sass loader for scss files and the scss file related to the project works fine, but if I import a scss file in the stories index.ts file, this file it is not loaded.
stories/index.ts
import { storiesOf } from '#storybook/angular';
import { action } from '#storybook/addon-actions';
import { VideoPosterComponent } from '../src/app/modules/ui-common/video-poster/video-poster.component';
//This scss it is not loaded
import '../src/styles.scss';
storiesOf('Video Poster component', module)
.add('Video Poster with author data', () => ({
component: VideoPosterComponent,
props: {
title: "Cinemagraph With Custom title",
subtitle: "This is a custom subtitle!"
}
}))
.add('Video Poster without author data', () => ({
component: VideoPosterComponent,
props: {}
}));
.storybook/webpack.config.js (recommended in here --> https://storybook.js.org/basics/guide-angular/#configure-style-rules)
const genDefaultConfig = require('#storybook/angular/dist/server/config/defaults/webpack.config.js');
module.exports = (baseConfig, env) => {
const config = genDefaultConfig(baseConfig, env);
// Overwrite .css rule
const cssRule = config.module.rules.find(rule => rule.test && rule.test.toString() === '/\\.css$/');
if (cssRule) {
cssRule.exclude = /\.component\.css$/;
}
// Add .scss rule
config.module.rules.unshift({
test: /\.scss$/,
loaders: ['raw-loader', 'sass-loader'],
});
return config;
};
And, the scss file for my component was loaded without problems
src/app/modules/ui-common/video-poster/video-poster.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-video-poster',
templateUrl: './video-poster.component.html',
styleUrls: ['./video-poster.component.scss'] // this were loaded without problems
})
export class VideoPosterComponent implements OnInit {
private hostUrl = 'https://s3-eu-west-1.amazonaws.com/video.gallereplay.com/portfolio/clients';
private baseUrl = `${this.hostUrl}/jaegermeister/Cinemagraph_plain/1920x1080`;
#Input()
public videoUrls = {
poster: `${this.baseUrl}/cinemagraph.jpg`,
mp4: `${this.baseUrl}/cinemagraph.mp4`,
webm: `${this.baseUrl}/cinemagraph.webm`,
}
#Input() public title = 'Custom Cinemagraph Productions';
#Input() public subtitle = 'Exclusive Content for Businesses';
constructor() { }
ngOnInit() {
}
}
Repository:
https://github.com/gpincheiraa/storybook-components-sample
run npm install && npm run storybook for check storybook running.
What I am doing wrong??
I assume that, like me, you're looking for a way to load global styles from SASS files into an Angular Storybook. I know it's been a while since you asked, but I came across this solution while searching for a way to accomplish this: https://github.com/storybookjs/storybook/issues/6364#issuecomment-485651328.
Basically, you can load your global styles in the Storybook config file. However, you need to use inline webpack loaders in the import path so Storybook will load them properly.
import '!style-loader!css-loader!sass-loader!../src/styles.scss';
That did the trick for me. In the end I didn't have to bother with the custom webpack config. Hopefully that solves your problem!
You are trying to import an scss file from your typescript. You must include it from your scss.
Please remove :
//This scss it is not loaded
import '../src/styles.scss';
In your scss file add :
#import "styles.scss";
In you angular.json add :
"styles": [
"src/styles.scss",
],
"stylePreprocessorOptions": {
"includePaths": [
"src/" // maybe not required in your case
]
},
In you .storybook/webpack.config.js please try :
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
loaders: ["sass-loader"],
include: path.resolve(__dirname, "../src/")
}
]
}
};
Otherwise there is the possibility to add an alias as Xdecus said here https://github.com/storybooks/storybook/issues/3814#issuecomment-401756776
const path = require('path');
module.exports = {
resolve: {
alias: {
styles: path.resolve(__dirname, '../src/')
}
}
};
All style imports must be in Component metadata (specifically in styles or styleUrls field). You're trying to import style file as js file, which is wrong.

Categories

Resources