DEV Community

loading...
Cover image for 🔨 Build a web package with typescript! 🔥
Pixium Digital

🔨 Build a web package with typescript! 🔥

Médéric Burlet
『  』| Passionate Coder | Idea Hurricane
・3 min read

👋🏻 Introduction

Here at Pixium we often find ourselves creating web packages for various websites.

This means a simple package that you can integrate via the script tag and then use in your code for example:

<script src="https://mycdn.a/latest/bundle.js"></script>
<script>
    pixiumPackage.helloWorld()
</script>
Enter fullscreen mode Exit fullscreen mode

During the development of this package we often find ourselves recreating all the package.json scripts and information. Thus we decided to create a template that can easily be setup.

In this post we will look at what tools we use and how we came to creating this kick-ass template!

power gif

🔧 Tools Used

Here is a quick list of tools used and a quick description of how it is used in the project

Tool Description
Yarn Handle package installation
Npm Publish the package to npm registry
Typescript Strongly typed JavaScript
Webpack Bundle the typescript into a single JavaScript Library
Snowpack Hot Module Reload for testing
Concurrently Start multiple commands at the same time

🗄️ Managing Structure

Let's take a look now at how we manage folders and files in our current project

code gif

webpack-demo/
├── README.md
├── dist
├────...
├── node_modules
├────...
├── package.json
├── snowpack.config.js
├── src
├────...
├── test
├────...
├── tsconfig.json
├── webpack.config.js
└── yarn.lock
Enter fullscreen mode Exit fullscreen mode

As we can see we have 4 main folders in our project:

Folder Use
dist Contains compiled ready for release bundle
node_modules All the npm packages needed for the project
src The source files of the library
test A index file referencing the bundle to test in real time

🕸 Webpack

In this project we use webpack and ts-loader.

Webpack is used for bundling everything in a library that is exposed in the browser while ts-loader let's us handle all the typescript necessities.

For the webpack config we use the output:library property to specify the name of the exposed library.

webpack.config.js

const path = require('path');

module.exports = {
    entry: './src/index.ts',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
    },
    output: {
        // Define the package name
        library: 'pixiumPackage',
        libraryTarget: 'umd',
        globalObject: 'this',
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};
Enter fullscreen mode Exit fullscreen mode

This means we can then access the library like this:

<script>
    pixiumPackage.myFunctionName()
    pixiumPackage.myClassName()
</script>
Enter fullscreen mode Exit fullscreen mode

❄️️ Snowpack

Snowpack is an awesome tool that we discovered recently at Pixium. It is a modern frontend build tool that is so fast!

fast gif

In this project Snowpack has a very simple use. Rendering a test environment to visualize changes in real time. It supports Hot Module Replacement which means everytime webpack will recompile a new bundle after making some changes the test environment will reload

snowpack

snowpack.config.js

/** @type {import("snowpack").SnowpackUserConfig } */
module.exports = {
    mount: {
        test: '/',
        dist: '/dist',
    },
    plugins: ['@snowpack/plugin-typescript'],
    install: [
        /* ... */
    ],
    installOptions: {
        installTypes: true,
    },
};
Enter fullscreen mode Exit fullscreen mode

Here the mount parameter is the most important.

  • test: '/', means we will mount the test folder as the root of the web
  • dist: '/dist' means we will mount the dist folder to /dist. This means that we can then require scripts from dist for instance <script src="./dist/bundle.js"></script>

💻 Exposing our Code

And now let's finish off with taking a look at the code and how we can expose our constants, functions, class.

typing gif

To make code accessible through our library we simply have to use the export method. For instance:

/**
 * Say hello world in the console
 */
export const PixiumHello = () => {
    console.log(`hello world`)
}
Enter fullscreen mode Exit fullscreen mode

We can then call this in the following way:

<script>
pixiumPackage.PixiumHello()
</script>
Enter fullscreen mode Exit fullscreen mode

You can also easily interact with the DOM through classic functions:

// Set the inner text
document.getElementById("pixiumBanner").innerText = "Pixium Digital Pte Ltd";
Enter fullscreen mode Exit fullscreen mode

🏁 Conclusion

We now have a very simple typescript bundling in place with a HMR system in place for easy testing.

There are a few command shortcuts implemented to easily push patches, minors, majors to npm.

All this coupled with a CDN and you get an awesome blazing fast library for your frontend.

Full repo bellow

GitHub logo pixiumdigital / typescript-package-boilerplate

webpack package with typescript support

Typescript Webpackage Boilerplate

In this boilerplate we have a simple look at a very basic typescript package exported for the web.

We leverage the use of webpack to expose our package to the browser.

Installation

install the dev packages with yarn:

yarn

Developement

yarn start

This will start webpack to compile the library on changes. This will also start snowpack which will update the index.html in test once the library from webpack has been compiled

Build

yarn build

Publish Package

First login to the npm cli if not already done

npm login

You will need to remove the following line in your package.json

private: true,

To publish a patch

yarn patch

To publish a minor

yarn minor

To publish a major

yarn major

Pixium Digital - Shaping your project with technology and innovation
https://pixiumdigital.com
https://github.com/pixiumdigital

Discussion (2)

Collapse
jffrydsr profile image
Jeffrey Desir

A thousand thanks! 🙏🏿
Snowpack should really be de-facto, huh? 😻
I appreciate the scaffolding ~

Collapse
crimsonmed profile image
Médéric Burlet Author

Hey Jeffrey! Thanks for the kind words!

We will build more templates and scaffolding when we can!

Since I've been starting to use snowpack I love how fast it it.