Intro
This is the third post in the series of blog posts describing about buildingGlimmer.js apps with general purpose bundlers. The previous posts walked you through building Glimmer apps withSnowpack andRollup. You can check them out here.
With Snowpack
With Rollup
In this post, we are going to build our Glimmer.js apps with a build tool calledWeb Dev Server
What is Web Dev Server?
Web Dev Server
helps developing for the web, using native browser features likeES modules. It is powered byesbuild andRollup. esbuild is an extremely fast JavaScript bundler and minifier written inGo.
I came across this tool fromModern Web Dev which is an awesome project from the creators orOpen Web Components, with a goal to provide developers with the guides and tools they need to build for the modern web. They enable developers to work closely with the browser and avoid complex abstractions.
Web Dev Server is ideal forbuildless workflows, and has a plugin architecture for light code transformations. It has got many features like efficient browser caching for fast reloads, compatibility with older browsers, auto-reload on file changes, History API fallback for Single Page Apps(SPA) routing, plugins and middleware API for non-JS files.
Setting up the project
mkdir glimmer-web-dev-servercd glimmer-web-dev-servernpm init -y
Addingsrc
directory for source files:
mkdir srccd srctouch App.js App.css
App.js
importComponent,{hbs}from'@glimmerx/component';importlogofrom'./logo.svg';importstylesfrom'./App.css';exportdefaultclassAppextendsComponent{constructor(){super(...arguments);this.styles=styles;this.logo=logo;}statictemplate=hbs` <div class={{this.styles.intro}}> <img src={{this.logo}}/> <h1>Hello World, glimmerx!</h1> <h3> you can get started by editing <code>src/App.js</code></a> </h3> </div> `;}
Please note that we are going to use CSS Modules for our component with PostCSS. We will discuss about this later.
App.css
.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;}
Addingdemo
directory for index.html and main JS file:
mkdir democd demotouch index.html index.js
Next we create ourindex.html
file with the following markup, we need a mount-point for our main component to load in the DOM and we need to include theindex.js
file as a module with<script type="module">
.
index.html
<!DOCTYPEhtml><html><head><title>GlimmerXwithweb-dev-server</title></head><body><divid="app"></div><scripttype="module"src="./index.js"></script></body></html>
Now the main index.js file will render ourApp
component in the DOM node#app
.
index.js
import{renderComponent}from'@glimmerx/core';importAppfrom"../src/App.js";renderComponent(App,document.getElementById('app'));
Adding dependencies
We need to install the@glimmerx
libraries for creating and rendering our Glimmer components.
yarn add @glimmerx/component @glimmerx/core
Adding devDependencies
Adding @web/dev-server dependencies
yarn add -D @web/dev-server @web/dev-server-esbuild
Configuring @web/dev-server
Now, it's time to create the configuration file. Web Dev Server looks for a configuration file in the current working directory calledweb-dev-server.config.*
The file extension can be.js
,.cjs
or.mjs
. A.js
file will be loaded as an ES module or Common JS module based on your version of node, and the package type of your project.
The Web Dev Server core team recommends writing the configuration using Node.js ES module syntax and using the.mjs
file extension to make sure your config is always loaded correctly.
touch web-dev-server.config.mjs
web-dev-server.config.mjs
import{esbuildPlugin}from"@web/dev-server-esbuild";exportdefault{nodeResolve:true,plugins:[],};
Let's start building our configuration step-by-step. First we need to compile our JS from the component source files. We are going to use Rollup and Babel for the same. Let's install the required packages for rollup and babel plugins.
For babel
yarn add -D @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/preset-env
For compiling our Glimmer components with the inline handlebars syntax we need to install the@glimmerx/babel-plugin-component-templates
, about which you can know more inhere.
yarn add -D @glimmerx/babel-plugin-component-templates
We need an Adapter forusing rollup plugins in Web Dev Server. Web Dev Server plugins and rollup plugins share a very similar API, making it possible to reuse rollup plugins inside Web Dev Server with an adapter.
For Rollup we need
yarn add -D @web/dev-server-rollup @rollup/plugin-babel
Let's add our babel plugins to the config file.
import{esbuildPlugin}from"@web/dev-server-esbuild";import{fromRollup}from'@web/dev-server-rollup';import*asbabelModulefrom'@rollup/plugin-babel';const{babel}=babelModule;constbabelPlugin=fromRollup(babel);exportdefault{nodeResolve:true,plugins:[babelPlugin({babelHelpers:'bundled',plugins:['@glimmerx/babel-plugin-component-templates',['@babel/plugin-proposal-decorators',{legacy:true}],'@babel/plugin-proposal-class-properties',],}),],};
We are importing the babel rollup plugin and thefromRollup
function in our configuration file. Then, we are wrapping the rollup plugin with the adapter function to make it work.
Now it's time to add our scripts in the package.json to start our dev server and build our source files.
"start":"web-dev-server --open demo/ --node-resolve --watch"
What we are doing here is to tell the web-dev-server to open and watch thedemo
folder for file changes and use the--node-resolve
flag to resolve bare module imports for use in the browser.
So now you can start the web-dev-server to load our app in the browser by issuing the following command:
yarn start
And if you go to the urlhttp://localhost:8000/demo
in your browser, you probably get a blank page and some errors in the console. The reason being that we have not yet configured our web-dev-server to process the CSS and images since the build process assumes that any imported files are meant to be compiled to JS, Web Dev Server serves many different kinds of files to the browser. If you are transforming a non-standard filetype to JS, for example.css
or.svg
files, you need to instruct the server to handle it as a JS file.
Let's handle them now using our Rollup pluginsrollup-plugin-postcss
and@rollup/plugin-image
.
yarn add -D @rollup/plugin-image rollup-plugin-postcss
This allows us to use the PostCSSCSS Modules feature which we discussed earlier. With that we don't have to worry about style clashes and naming our css classes and selectors since all of them will be properly scoped and encapsulated. We can import our style definitions in our components and use them like:
importstylesfrom'./App.css';...<divclass={{styles.intro}}/>
And now, add these plugins for loading css and images to our config.
...importpostcssfrom'rollup-plugin-postcss';importimagefrom'@rollup/plugin-image';...constpostcssPlugin=fromRollup(postcss);constimagePlugin=fromRollup(image);exportdefault{...plugins:[...postcssPlugin({include:['src/**/*.css'],modules:true}),imagePlugin()],mimeTypes:{'**/*.css':'js','**/*.svg':'js'}};
In the above config, we are telling therollup-plugin-postcss
to include all the css files inside the src folder and use CSS modules with the modules option set to true.
And we also need to tell web-dev-server to load all thecss
andsvg
files as JS with themimeTypes
option.
Now this is how the full and final config for our web-dev-server looks like.
import{esbuildPlugin}from"@web/dev-server-esbuild";import{fromRollup}from'@web/dev-server-rollup';import*asbabelModulefrom'@rollup/plugin-babel';importpostcssfrom'rollup-plugin-postcss';importimagefrom'@rollup/plugin-image';const{babel}=babelModule;constbabelPlugin=fromRollup(babel);constpostcssPlugin=fromRollup(postcss);constimagePlugin=fromRollup(image);exportdefault{nodeResolve:true,plugins:[babelPlugin({babelHelpers:'bundled',plugins:['@glimmerx/babel-plugin-component-templates',['@babel/plugin-proposal-decorators',{legacy:true}],'@babel/plugin-proposal-class-properties',],}),postcssPlugin({include:['src/**/*.css'],modules:true}),imagePlugin()],mimeTypes:{'**/*.css':'js','**/*.svg':'js'}};
Now restart our server and visithttp://localhost:8000/demo
url in the browser. Your app should look like the this.
Source code
The source code for this post can be found in thisGithub repository. The repository also contains some bonus stuff of writing tests for your Glimmer components and running tests withWeb Test Runner another awesome tool from the Modern Web project.
This concludes our Building Glimmer apps series with different bundlers. Please let me know in the comments if you have any queries or feedback, I will be glad to answer the same.
Top comments(2)

This is really interesting! I'd love to hear how you'd deploy with one of these -- I'm assuming you'd use Rollup?

- LocationChennai
- EducationPondicherry University
- PronounsHe
- WorkFront-end Architect
- Joined
Yes
For further actions, you may consider blocking this person and/orreporting abuse