Intro
This is the second post in the series of posts describing building Glimmer.js apps with various bundlers likeSnowpack, Rollup, etc., If you want to check out the first post where we build Glimmer apps with Snowpack, it can be found here.
In this post, we will be usingRollup to build our Glimmer apps.
Before diving into the topic, let's have a brief introduction about Glimmer and Rollup
About Glimmer
Glimmer is one of the fastest DOM rendering engines, delivering exceptional performance for initial renders as well as updates. Architected like a virtual machine (VM), Glimmer compiles your templates into low-level code so it can run as fast as possible—without sacrificing ease of use. Glimmer VM powers the components inEmber.js
About Rollup
Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized ES Modules(ESM) format for code modules. ESM lets you freely and seamlessly combine the most useful individual functions from your favorite libraries.
Setting up project
mkdir glimmer-rollupcd glimmer-rollupnpm init -ymkdir src publictouch src/index.js src/App.js src/App.csstouch public/index.html
index.html
Let's create our index.html file with some markup. We will be including two main things here: thedist/bundle.css
anddist/bundle.js
for the final CSS and JS builds of our apps respectively.
<!doctype html><html><head><title>glimmer-rollup</title><linkrel="icon"href="./public/favicon.png"/><linkrel="stylesheet"href="dist/bundle.css"></head><body><divid="app"></div><scriptsrc="dist/bundle.js"></script></body></html>
src/index.js
And in theindex.js
file which is the main entry point of our app, we will be importing our App component and mount it on the DOM with therenderComponent
function which takes two parameters, a component and a DOM node.
import{renderComponent}from'@glimmerx/core';importAppfrom'./App';constcontainerElement=document.getElementById('app');renderComponent(App,containerElement);
src/App.js
OurApp
component is a simple one, where we just display a logo and some text. We are importing the logo from an svg file using the standard import syntax. Similarly we import the style definitions for our component from a css file calledApp.css
. This is a pretty common thing with other component based frameworks like React, and with bundlers like Webpack we will use the appropriate loader plugins to import non-JS stuff like images and css into our components. In case of Rollup, we will be using some Rollup plugins to do the job.
importComponent,{hbs}from'@glimmerx/component';importlogofrom'./logo.svg';import'./App.css';exportdefaultclassAppextendsComponent{logo=logo;statictemplate=hbs` <div> <img src={{this.logo}}/> <h1>Hello World, glimmerx!</h1> <h3> you can get started by editing <code>src/App.js</code> </h3> </div> `;}
src/App.css
This is how our style definitions will look like for our components. As you can see for the sake of brevity I have used id selectors to style the components, normally it is not recommended, but instead you can use re-usable class definitions or alike.
body{margin:0;}#app{background:#1E293B;min-height:100vh;display:grid;align-items:center;justify-content:center;}#intro{width:34em;}#introh1,#introh3{font-family:Roboto,'Helvetica Neue',Helvetica,Arial,sans-serif;font-style:italic;color:#FFFFFF;margin:0.35em;}#introimg{float:left;width:6.5em;margin:0.5em2em;}#introa{color:#FFFFFF;}
Configuring Rollup
First, you need to install rollup and the necessary plugins and then create a config file for Rollup to direct the build process. For a bare minimum build setup, we need the following three official Rollup plugins to be installed in our project as dev dependencies.
@rollup/plugin-node-resolve
This is a Rollupplugin which locates modules using the Node resolution algorithm, for using third party modules innode_modules
@rollup/plugin-commonjs
This is a Rollupplugin to convert CommonJS modules to ES6, so they can be included in a Rollup bundle.
@rollup/plugin-babel
This is a Rollupplugin for seamless integration between Rollup andBabel. We need Babel to compile our Glimmer components with advanced ES syntax using decorators and class properties.
yarn add -D rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-babel
So we also need to setup our babel plugins by creating a babel config.babelrc.js
with the following setup. You can refer to theprevious post to see why we need the different babel plugins and what each one does.
module.exports=function(api){return{plugins:[['@glimmer/babel-plugin-glimmer-env',{DEBUG:!api.env('production')}],'@glimmerx/babel-plugin-component-templates',['@babel/plugin-proposal-decorators',{legacy:true}],'@babel/plugin-proposal-class-properties',],presets:['@babel/preset-env'],};};
We should also install the necessary babel plugins for our project.
yarn add @babel/preset-env @glimmer/babel-plugin-glimmer-env @glimmerx/babel-plugin-component-templates @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
Then we need to create a rollup config file calledrollup.config.js
in our root folder.
/* globals process */importnodeResolvefrom'@rollup/plugin-node-resolve';importcommonjsfrom'@rollup/plugin-commonjs';importbabelfrom'@rollup/plugin-babel';constplugins=[nodeResolve(),commonjs({include:'node_modules/**',}),babel(),];exportdefault{input:'./src/index.js',output:{file:'public/dist/bundle.js',},plugins,};
Now, we need a development server to watch the file changes, rebuild the assets and serve them in the browser.
Setting up development server
If you want to setup a development server for our project, we need to install therollup-plugin-serve plugin into our project and add it to ourrollup.config.js
.
yarn add -D rollup-plugin-serve
/* globals process */importnodeResolvefrom'@rollup/plugin-node-resolve';importcommonjsfrom'@rollup/plugin-commonjs';importbabelfrom'@rollup/plugin-babel';importservefrom'rollup-plugin-serve';constIS_PRODUCTION=process.env.NODE_ENV==='production';constplugins=[...!IS_PRODUCTION&&serve({open:true,port:8080,contentBase:'public',}),];...
Now you can add a npm script in yourpackage.json
"scripts":{..."start":"rollup -c -w",...},
Here we are invoking the rollup cli with-c
option to use therollup.config.js
as the configuration and-w
to watch for file changes. You can read more about configuring the rollup cli with various options and flagshere in the official documentation.
And you can start the build by issuing the following command:
yarn start
But you will get an error something like this in the console
Your build won't run because it's missing the necessary plugins to load images and styling which we will take care now.
Importing images
Install the@rollup/plugin-image
plugin for importing images in different formats into our components.
yarn add -D @rollup/plugin-image
Importing css
For importing CSS files into our components, you can make use of therollup-plugin-css-only
yarn add -D rollup-plugin-css-only
Then we add these plugins to our rollup config.
/* globals process */...importimagefrom'@rollup/plugin-image';importcssfrom'rollup-plugin-css-only';...constplugins=[...image(),css({output:'bundle.css'}),...];...
Now we can start the server and watch for file changes and the re-build will be triggered automatically. Rollup will automatically open your browser and go to the page athttp://localhost:8080
to run our app, since we have configured the same in the rollup config file. And this is how our app should look like in the browser.
For live reloading changes, you can also install and use therollup-plugin-livereload.
Minifying for production
So, the next thing we will looking at is how to minify our build output for production. For this we will make use of another Rollup plugin calledrollup-plugin-terser and add it to the list of plugins in the rollup config.
yarn add -D rollup-plugin-terser
And then we add a build script to our package.json to use rollup to build for production
"scripts":{..."build":"NODE_ENV=production rollup -c","start":"rollup -c -w",...},
Now you can run build the command for creating production optimised bundles:
yarn build
Final rollup configuration
This is how our rollup config file will look like in the end.
/* globals process */importnodeResolvefrom'@rollup/plugin-node-resolve';importcommonjsfrom'@rollup/plugin-commonjs';importimagefrom'@rollup/plugin-image';importcssfrom'rollup-plugin-css-only';importbabelfrom'@rollup/plugin-babel';importservefrom'rollup-plugin-serve';import{terser}from'rollup-plugin-terser';constIS_PRODUCTION=process.env.NODE_ENV==='production';constplugins=[nodeResolve(),commonjs({include:'node_modules/**',}),image(),css({output:'bundle.css'}),babel(),!IS_PRODUCTION&&serve({open:true,port:8080,contentBase:'public',}),IS_PRODUCTION&&terser(),];exportdefault{input:'./src/index.js',output:{file:'public/dist/bundle.js',},plugins,};
Source code
The source code for this tutorial is available inGithub. You can fork and clone this project or you can use a tool something likedegit to use this template.
npx degit rajasegar/glimmerx-rollup my-glimmerx-app
What's next?
In the next post in this series, we will take a look at bundling Glimmer apps with a more "modern" bundling tool. So stay tuned by followingme for any updates, you can also let me know your feedback and suggestions in the comments below.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse