I’m at the Polymer Summit in London today, and finally writing up a build process for Polymer apps hosted on Firebase that I’m satisfied with enough to recommend.
The problem is this: if you create an app using web components installed with Bower, and import each component using <link rel="import" href="bower_components/component-name/component-name.html">
, the bower_components
folder will be inside your app
folder.
This is fine for development, but when you deploy the app to a remote server (e.g. Firebase), you don’t want all the files in the bower_components
folder to be deployed to the public server as part of your app - not only does it take much longer to upload, but there could be security problems with demo files hiding in any of the component folders.
So you need a build process, which builds the public app in a build
folder and deploys that folder instead, without the `bower_components` folder.
The Makefile for this build process is quite straightforward:
.PHONY: clean lint build deploy serve
all: build
clean:
rm -rf build
lint:
# node_modules/polylint/bin/polylint.js
node_modules/standard/bin/cmd.js
build: clean lint
cp -r app build
node_modules/vulcanize/bin/vulcanize --inline-scripts --inline-css app/elements.html -o build/elements.html
deploy: build
firebase deploy --public build
serve:
firebase serve
Running make build
builds the app: first making a copy of the app
folder called build
, then running vulcanize
on app/elements.html
(which includes all the <link rel="import" href="…">
imports) to create a single build/elements.html
file containing all the imported code. It inlines all the script and style dependencies of those components, so everything is imported from build/elements.html
instead of individual files in bower_components
.
There are a few more things the build process can/could do: lint the app using polylint
(currently disabled as it finds too many errors in third-party components) and lint the JavaScript using standard
. It could also run crisper
to move all the inline JS and CSS into separate files, but I haven’t done that here.
Running make deploy
runs firebase deploy
, setting build
as the public folder. The “ignore” setting in the firebase.json
file (see below) tells it not to upload anything in bower_components
, so in the end only a few files are uploaded and deployed.
{
"hosting": {
"public": "app",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**",
"**/bower_components/**"
],
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
}
}
index.html
is untouched, leaving it readable as a manifest and allowing it to be loaded and parsed quickly.