I'm new to both Polymer and Webpack and trying to work out how to get the polymer-webpack-loader transpiling correctly. According to the new Polymer 3.x way of importing HTML into JS (Polymer 2.x was the other way round), I've created a separate .html file and attempting to import it into my 'extends PolymerElement' class.
Here is my simple template.html file:
<div>This is my chosen colour: [[colour]] (Made by the [[name]] app)</div>
Here is my Polymer index.js file:
import { PolymerElement, html } from '@polymer/polymer';
import * as view from './template.html';
export class NpsWidget extends PolymerElement {
static get is() { return 'nps-widget'; }
// Define a string template instead of a `<template>` element.
static get template() {
return html(`${view}`);
}
constructor() {
super();
this.name = 'Polymer 3.0 test';
console.log(this.name + ' constructor run successfully.');
}
static get properties() {
return {
name: {
type: String
},
colour: {
type: String,
value: '#777777'
}
};
}
}
customElements.define(NpsWidget.is, NpsWidget);
And here's my webpack config file:
const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const pkg = require(path.resolve(__dirname, '../package.json'));
let libraryName = pkg.name;
const config = {
mode: 'development',
entry: path.resolve(__dirname, '../src/index.js'),
devtool: 'source-map',
output: {
globalObject: 'typeof self !== \'undefined\' ? self : this',
path: path.resolve(__dirname, '../lib/dev'),
filename: libraryName + '.js',
library: libraryName,
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
rules: [
{
test: /\.html$/,
use: [
// Chained loaders are applied last to first
{ loader: 'babel-loader' },
{ loader: 'polymer-webpack-loader' }
]
},
{
test: /\.js$/,
// We need to transpile Polymer itself and other ES6 code
// exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: [[
'env',
{
targets: { browsers: ['last 2 Chrome versions', 'Safari 10'] },
debug: true
}
]],
plugins: [['transform-object-rest-spread', { useBuiltIns: true }]]
}
}
},
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
{
test: /(\.tsx|\.ts)$/,
loader: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
modules: [path.resolve(__dirname, '../node_modules'), path.resolve(__dirname, '../src')],
extensions: ['.ts', '.tsx', '.json', '.js', '.html']
},
plugins: [
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: 'static',
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js')
},
{
from: path.resolve(__dirname, '../node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js')
}
])
]
};
module.exports = config;
The result that I get is that the import statement in the template.html seems to be simply creating the div tag in the bundled script and including it in the document and of course the class can't find the value... Here's the output:
This is my chosen colour: [[colour]] (Made by the [[name]] app)
undefined
If I include the template in a literal HTML string in the JS file and remove the import statement, it works fine:
//import * as view from './template.html';
...
return html`<div>This is my chosen colour: [[colour]] (Made by the [[name]] app)</div>`;
This is my chosen colour: #777777 (Made by the Polymer 3.0 test app)
Can anyone help me understand how to get this to work? I suspect it's some configuration to do with polymer-webpack-loader. This style of code works fine in a vanilla Polymer app that isn't being bundled by Webpack.
Thanks,
Paul