import QRCode constructor for Javascript through webpack - javascript

I want to use the QRCode generator from this repo: https://github.com/davidshimjs/qrcodejs
How do I import the QRCode through webpack? When I installed qrcodejs through npm the index.js contained this code module.exports = 'qrcodejs'; When I use require('qrcodejs'); in my code it returns the string 'qrcodejs', but I want to import the QRCode constructor through webpack. I want to be able to call the constructor in my code like so, after importing it with webpack.
let qrcode = new QRCode("output", {
text: "http://google.com",
width: 100,
height: 100,
colorDark: "#188710",
colorLight: "#ffffff"
});
What do I have to do to accomplish this? I am using ES6 Javascript without any frameworks or other libraries, besides webpack.
UPDATE
index.js inside the qrcodejs folder
module.exports = {
module: {
rules: [
{ test: /qrcode/, loader: 'exports-loader?QRCode' }
]
}
}
myproject.js
import { QRCode } from 'qrcodejs'
export class EditProduct {
openProduct(){
let test = require('qrcodejs'); // returns the module object with the rules array
let test2 = QRCode // returns undefined
}
}

Just as Raz Ronen said, install export-loader.
This will allow us to introduce non-modular js to Webpack.
After installing add the QRCode module as:
import QRCode from 'exports-loader?QRCode!qrcodejs/qrcode'
based on the answer here

Use export-loader to make module.export = <anything you want>
basiclly what you want is to have qrcode.min.js module.export return QRCode.
You can define a rule for it:
module: {
rules: [
{ test: /qrcode/, loader: 'exports-loader?QRCode' }
]
}

Related

How to dynamically bundle module/object in RollupJs output?

How can I dynamically bundle a module/object into my RollupJs output file? I have tried a ton off different options but can not get the expected output I am looking for.
I put together a short sample project below to help illustrate what I am looking for. The expected output should print "Hello John Doe" from the overrideApp object that is dynamically injected as a dependency.
src/app.js
export default {
sayHello: function() {
console.log('Hello Mr.Roboto')
},
sayGoodBye: function() {
console.log('Goodbye Mr.Roboto')
}
}
index.js
import app from './src/app.js'
import overrideApp from 'overrideApp'
export default { ...app, ...overrideApp }.sayHello()
.rollup.config.js
let overrideApp = {
sayHello: function() {
console.log('Hello John Doe')
}
}
export default [
{
input: 'index.js',
external: ['overrideApp'], // This is not working, expecting to pass overrideApp to index.js
output: {
file: './dist/app.js',
format: 'umd',
name: 'bundle',
}
}
]
This is totally correct your mixing here a lot of stuff together that does not work together.
You are looking for a virtual module
Install
npm install #rollup/plugin-virtual --save-dev
Usage
Note. Use this plugin before any others such as node-resolve or commonjs, so they do not alter the output.
Suppose an entry file containing the snippet below exists at src/entry.js, and attempts to load batman and src/robin.js from memory:
// src/entry.js
import batman from 'batman';
import robin from './robin.js';
console.log(batman, robin);
Create a rollup.config.js configuration file and import the plugin:
import virtual from '#rollup/plugin-virtual';
export default {
entry: 'src/entry.js',
// ...
plugins: [
virtual({
batman: `export default 'na na na na na'`,
'src/robin.js': `export default 'batmannnnn'`
})
]
};
https://github.com/rollup/plugins/edit/master/packages/virtual

Webpack 4, how to import a module into another module that are both entry points?

I'm new to Webpack, so my terms may not be entirely correct. What I'm trying to do is build a custom Phaser module first, then import it into the other entry point, which depends on it.
EDIT: I've tried using SplitChunks, Dynamic Imports, and aliases. But no avail. Is there anyway to accomplish this via plugins or methodology?
From webpack.config.js:
entry: {
'phaser.min': './phaser-builder.js',
game: './src/index.js'
},
resolve: {
alias: {
'eventemitter3': path.resolve(__dirname, './node_modules/eventemitter3')
},
modules: [ 'node_modules/phaser/src', 'node_modules' ]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js',
library: 'Phaser',
libraryTarget: 'umd',
sourceMapFilename: '[file].map',
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]',
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]',
umdNamedDefine: true
},
Contents of phaser-builder.js:
require('polyfills');
var CONST = require('const');
var Extend = require('utils/object/Extend');
var Phaser = {
... code ...
};
Phaser = Extend(false, Phaser, CONST);
module.exports = Phaser;
global.Phaser = Phaser;
index.js (second entry point) needs the 'Phaser' object from phaser.min.js that is created from ./phaser-builder.js (first entry point) as shown below:
Contents of index.js:
//import 'phaser'; //this works but it's not the custom build from entry point one.
import { Phaser } from '../build/phaser.min';
import { TestScene } from './scenes/TestScene';
const gameConfig = {
width: 680,
height: 400,
scene: TestScene
};
new Phaser.Game(gameConfig);
Contents of TestScene.js: (imported in index.js)
export class TestScene extends Phaser.Scene {
preload() {
this.load.image('logo', 'assets/sprites/logo.png');
}
create() {
this.add.text(100, 100, 'Working...', { fill: '#0f0' });
this.add.image(100, 200, 'logo');
}
}
As commented in index.js above, if I simply use import 'phaser'; (which is pulling from node_modules I presume?) Everything works fine. But that is the full phaser lib, which I don't want. I want to import the custom build I created in entry point one, that exists in /build/phaser.min.js
If I try importing from /build/phaser.min.js I get this error:
"TypeError: Super expression must either be null or a function"
Which from my understanding is basically saying that Phaser object/module is undefined, so TestScene is not extending Phaser.Scene as expected.
With webpack I add specific build of phaser in the followed way, I hope this is what you are looking for or at least will give you any idea how could we do with webpack
thank you.

Gatsby.js - Typography themes

I'm creating an application based on gatsby framework, but I have problem with initialize gatsby theme. From official documentation:
https://www.gatsbyjs.org/tutorial/part-three/
import Typography from 'typography';
import fairyGateTheme from 'typography-theme-github';
const typography = new Typography(fairyGateTheme);
export const { scale, rhythm, options } = typography;
export default typography;
But typography-theme-github import has dotted underline when I hovered mouse on it I have got this tip:
Could not find a declaration file for module 'typography-theme-github'. '/Users/jozefrzadkosz/Desktop/hello-world/node_modules/typography-theme-github/dist/index.js' implicitly has an 'any' type.
Try npm install #types/typography-theme-github if it exists or add a new declaration (.d.ts) file containing declare module 'typography-theme-github';ts(7016)
When I run gatsby develop I'm getting this error:
Error: Unable to find plugin "undefined". Perhaps you nee d to install its package?
EDIT
I have looked on this file node_modules/typography-theme-github/dist/index.js and I found one similar issue:
var _grayPercentage = require("gray-percentage");
This require has exactly same tip as my theme import.
SECOND EDIT
Gatsby.config.js
module.exports = {
plugins: [
[`gatsby-plugin-sass`],
{
resolve: `gatsby-plugin-typography`,
options: {
pathToConfigModule: `src/utils/typography`
}
}
]
};
I notice you placed gatsby-plugin-sass in an array, which is why gatsby didn't recognize it:
module.exports = {
plugins: [
- [`gatsby-plugin-sass`], <-- error
+ `gatsby-plugin-sass`,
{
resolve: `gatsby-plugin-typography`,
options: {
pathToConfigModule: `src/utils/typography`
}
}
]
};
This is probably not a problem with gatsby-plugin-typography.

How to properly export an ES6 module function as a library for use in a node app?

Let's say that I have a node.js application, which does NOT go through my webpack bundling:
Node App
const Html = require('./build/ssr-bundle.js');
let result = Html.ssrbundle.render();
console.log(result);
Here is my ES6/JSX file, which is getting processed by webpack and I want to be able to access that render function in my node app (you guessed right, I am trying to SSR react stuff ;) )
src/Html.js -(webpack)-> build/ssr-bundle.js
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import CustomComponent from './custom-component.js';
module.exports = {
render : function () {
return ReactDOMServer.renderToString(<CustomComponent />);
} };
And here is my Webpack config
webpack.config.js
var path = require('path');
module.exports = {
entry: {
ssr: './src/Html.js',
//frontend: './src/frontend-Html.js'
},
output: {
path: path.resolve(__dirname, 'build'),
filename: 'ssr-bundle.js',
library: 'ssrbundle'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['env','react'],
plugins: ["transform-es2015-destructuring", "transform-object-rest-spread"]
}
},
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
},
stats: {
colors: true
},
devtool: 'source-map'
};
Whatever I do, I cannot figure out how to properly use that exported variable "ssrbundle" and subsequently the render function. If I had my node app included in the bundle, everything would be all right, but this is not what I want to do.
As apokryfos suggested, I played around with the libraryTarget Webpack setting. You can find more info on using Webpack to author a library (what I was really trying to achieve) here:
https://webpack.js.org/guides/author-libraries/
and here are code examples:
https://github.com/kalcifer/webpack-library-example/blob/master/webpack.config.babel.js.
What did the trick for me, was to set the libraryTarget to "umd" , which is different than the "var" setting which is set by default and is suitable i.e. for including the script in an HTML file

How to expose an es6 module globally

I need to write a module that will be available on the window global.
I'm using es6 to create the module and every single class I define has it's own file.
I'm using webpack to babelify and bundle these classes.
The entry point of my module is also the file containing the global to be exposed.
I've tried every method to make this possibe, icluding:
expose-loader
import-loader
expoert-loader
output: library
black-magic :(
Example of code I've tried:
I want to get: window.MyMod
// mymod.js
export class MyMod {
constructor(aaa) {
this.aaa = aaa;
}
toString() {
return this.aaa;
}
}
// webpack.config
var entries = [
'./src/mymod.js'
];
module.exports = {
...,
module: {
loaders: [
{
test: require.resolve('./src/mymod.js'),
loader: 'expose?MyMod'
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
]
}
This only gets me an object MyMod on the window that contains MyMod as a constructor.
Any help will be appreciated.
You should combine export default class Foo with the library and libraryTarget settings in Webpack's config. Something like:
// src/Foo.js
export default class Foo { ... }
// webpack.config.json
{
"output": {
"library": "Foo",
"libraryTarget": "var"
}
}
You should be able to use the library as window.Foo once the bundle has been loaded.
This is basically the same issue as Exporting a class with Webpack and Babel not working , except that you have a named export instead of a default export. Your entry file should be
import {MyMod} from './mymod';
module.exports = MyMod;
or
module.exports = require('./mymod').MyMod;
If you don't want to do any of these and keep './src/mymod.js' as entry file, use a CommonJS export instead of an ES6 export in that file:
// mymod.js
exports.MyMod = class MyMod {
constructor(aaa) {
this.aaa = aaa;
}
toString() {
return this.aaa;
}
}

Categories