webpack 4 library target umd x is not a constructor - javascript

i have this es6 class in my /src/index.js
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `(${this.x}, ${this.y})`;
}
}
export default Point;
here is the webpack.config.js file
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
library: 'point',
libraryTarget: 'umd',
umdNamedDefine: true,
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
};
so when i include in my index.html file like this:
<!DOCTYPE html>
<html>
<head>
<title>Webpack</title>
</head>
<body>
<!-- Scripts -->
<script src="dist/bundle.js"></script>
<script type="text/javascript">
new point(1, 3).toString()
</script>
</body>
</html>
so i have this error in console
"Uncaught TypeError: point is not a constructor"
this is umd script type
why i'm seeing this error while compile with webpack?
same scenario working fine with rollup
is there any solution?
and one more thing i saw almost every developer use rollup for es6 package development to compile "esm", "umd" versions of the script.
but i want to use webpack instead of rollup.
any guide?
thanks

Please add libraryExport: 'default', in output section of Webpack configuration.
something like this (for your case),
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
library: 'point',
libraryTarget: 'umd',
umdNamedDefine: true,
libraryExport: 'default',
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
};

Related

Webpack serve does not include exports on var

I'm working on a project using webpack, I'm trying to use the webpack-dev-serve package to preview my changes. However when I start the server and load the page the object created by webpack does not have the functions on it Uncaught TypeError: test.a is not a function, when I console log the object webpack creates I can see its an empty object Object { }. Using the exact same webpack config to build the package and including it on my page works fine.
Here is my webpack.config:
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
target: "web",
output: {
filename: "test.js",
library: {
name: "test",
type: "var"
}
},
module: {
rules: [{
exclude: /node_modules/
}]
},
resolve: {
symlinks: false
},
plugins: [
new HtmlWebpackPlugin({
title: "Development",
template: "./src/index.html",
scriptLoading: "blocking",
inject: "head"
})
]
};
My index.js is very simple:
export function a(){
console.log("A has been called");
}
My index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<script>
console.log(test);
test.a();
</script>
</body>
</html>
I found a fix from the problem here:
WebPack output.library.type var is undefined
After adding injectClient: false to devServer, and removing scriptloading and inject from the HtmlWebpackPlugin config, webpack serve now works as expects.

Setup webpack to require a file in end-user application

If I'm developing a node module like this:
// index.js in library
const loadRoutes = () => require('./routes.js')
export default loadRoutes
Then bundle it using webpack:
// webpack.config.js
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
mode: 'development'
}
Then in end-user application, when I import the library, I want require('./routes.js') to require routes.js relative to the app.
import loadRoutes from 'myLib'
loadRoutes()
But it throws an exception: Can not find module './routes.js'.
I tried to use webpack ignore plugin. But it's not working in the way I expected. Webpack configuration is:
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
plugins: [
new webpack.IgnorePlugin(/routes\.js/)
],
mode: 'development'
}
I don't know why such a useful thing should be that hard to be implemented in webpack. Am I doing it wrong? or what?

Polymer 3 in other project (like ASP.NET MVC) - create reusable components (PolymerElements)

I am trying to create and reuse Polymer 3 components in ASP.NET MVC application. Right now I am not sure if I am approaching the issue correctly.
So first thing, I want to run everything from IIS express.
Right now I have this issue:
Uncaught TypeError: Failed to resolve module specifier "#polymer/polymer/polymer-element.js".
Relative references must start with "/", "./", or "../".
Here is my code:
Index.cshtml:
<head>
<script src="~/Scripts/PolymerApp/node_modules/#("#webcomponents")/webcomponentsjs/webco
mponents-loader.js"></script>
<script type="module" src="~/Scripts/PolymerApp/first-element.js">
</script>
</head>
<h2>Index</h2>
<div>
<first-element></first-element>
</div>
This is my first-element.js:
import {html, PolymerElement} from '#polymer/polymer/polymer-element.js';
class FirstElement extends PolymerElement {
static get template() {
return html`
<style>
:host {
display: block;
}
</style>
<h2>Hello [[prop1]]!</h2>
`;
}
static get properties() {
return {
prop1: {
type: String,
value: 'first-element',
},
};
}
}
window.customElements.define('first-element', FirstElement);
I created this through cmd: polymer init and then chose element template.
When I run this through polymer serve on polymer`s localhost it works, so i guess there is some build process going on.
Thanks in advance. I hope that i described everything.
I've attempted to do a string replacement in the polymer generated html file using webpack and a plug-in, but it doesn't seem to find the file. Maybe someone more knowledgeable in Webpack-fu can figure out the rest.
// webpack.config.js
var webpack = require('webpack');
const ReplaceInFileWebpackPlugin = require('replace-in-file-webpack-plugin');
"use strict";
module.exports = {
entry: {
main: '/'
},
output: {
filename: "./wwwroot/dist/[name].bundle.js",
publicPath: "/temp/"
},
devServer: {
contentBase: ".",
host: "localhost",
port: 9000
}, mode: "development",
plugins: [
new ReplaceInFileWebpackPlugin([{
dir: './path/to/polymer-built-app/build/default/',
test: /\.html$/,
rules: [{
search: '/#webcomponents/',
replace: '/#{\'#webcomponents\'}/'
}]
}])
]
};
**EDIT: 08/04/2018 **
I've figured this much out:
/// <binding BeforeBuild='Run - Development' />
// webpack.config.js
var webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackStringReplacePlugin = require('html-webpack-string-replace-plugin');
"use strict";
module.exports = {
entry: {
main: './'
},
output: {
publicPath: '/',
path: path.resolve(__dirname, 'wwwroot'),
filename: "./dist/[name].bundle.js"
},
devServer: {
contentBase: ".",
host: "localhost",
port: 9000
},
mode: "development",
plugins: [
new HtmlWebpackPlugin({
"template": "./path/to/index.html",
"filename": "../path/to/Views/Shared/_PolymerLayout.cshtml"
}),
new HtmlWebpackStringReplacePlugin({
'#webcomponents':
'#Html.Raw("#webcomponents")',
'%40webcomponents':
'#Html.Raw("#webcomponents")',
'%40polymer':
'#Html.Raw("#polymer")',
'/node_modules/':
'/path/to/node_modules/',
'./src/path/to/polymer-app',
'<!-- See google short url -->':
'<!-- See google short url -->\r\n<base href="/custom/base/ref">'
})
]
};
If the .js import path starts like this:
from '#polymer/...'
Polymer 3 has a command "polymer build" that automatically translates the path to a real location:
Before:
from '#polymer/polymer/polymer-element.js';
After:
from "./node_modules/#polymer/polymer/polymer-element.js";
You can type ./node_modules/ in front to skip using the polymer build command line tool.

How to export bundled libraries in my vendor.js (CommonsChunkPlugin)?

I have two webpack 2 projects
The 1st one, let's call it lib1 is a library of reusable React components. In the webpack config it is exported as a library with the name lib1. The project lists react and react-dom as external dependencies.
The 2nd one, let's call it proj1 is an app that uses lib1. Because lib1 is served on a cdn, it's listed as an external dependency. The project also depends on react and react-dom. Using CommonsChunkPlugin I generare a vendor.js that includes react and react-dom (and eventually other dependencies).
When I run proj1 in the browser, the code inside lib1 fails because it can't find react. The libraries are loaded in this order:
<script src="dist/vendor.js"></script>
<script src="http://cdn.com/lib1/lib1.js"></script>
<script src="dist/bundle.js"></script>
I guess the issue is that react and react-dom are not exported by my vendor.js file.
I tried using the library option like this (int proj1):
library: "[name]",
libraryTarget: "umd"
But it creates window.vendor not window.React and window.ReactDOM.
How do I do that?
lib1 config
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, "dist"), // string
filename: "bundle.js",
publicPath: "/dist/",
library: "lib1",
libraryTarget: "umd",
},
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: path.resolve(__dirname, "node_modules"),
}]
},
externals: ["react", "react-dom"],
};
proj1 config
var webpack = require('webpack');
const path = require('path');
module.exports = {
entry: {
bundle : './src/index.js',
vendor : ['react', 'react-dom']
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js",
publicPath: "/dist/",
library: "[name]",
libraryTarget: "umd",
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'
})
],
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: path.resolve(__dirname, "node_modules"),
}]
},
externals: ["lib1"],
devtool: "source-map"
};

Webpack - Best way to update HTML to include latest [hashed] bundles

I'm using webpack to generate hashed bundle filenames.
Assuming I'm using static HTML, CSS & JS, what is the best way to automatically update index.html to point to the latest bundles?
For example,
update:
<script src="e8e839c3a189c25de178.app.js"></script>
<script src="c353591725524074032b.vendor.js"></script>
to:
<script src="d6cba2f2e2fb3f9d98aa.app.js"></script>
<script src="c353591725524074032b.vendor.js"></script> // no change
automatically everytime a new bundle version is available.
Amazingly, this is what the html-webpack-plugin is for.
var webpack = require('webpack');
var path = require('path');
var HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = function(env) {
return {
entry: {
main: './src/index.js',
vendor: 'moment'
},
output: {
filename: '[chunkhash].[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
new HTMLWebpackPlugin({
tempate: path.join(__dirname, './src/index.html')
})
]
}
};
This generates an index.html in the dist directory that includes the script's in the correct order.
youtube example

Categories