DEV Community

loading...
Cover image for Setting up the development environment for js13k

Setting up the development environment for js13k

yvonnickfrin profile image 🦁 Yvonnick FRIN ・6 min read

This article is the second entry of a devlog on my participation to js13k competition with MogSogeking


As we start developing our game, there are some tasks we want to avoid doing manually like:

  • reloading our game each time we do some change;
  • creating our submission file;
  • checking if we reach the 13k limit;
  • deploying our game to a public url (it is nice to gather feedback during development);

Before choosing a tool to help us achieve the tasks listed above it is important to know how our code must be structured. Here is the rule of js13k competition about the folder structure.

Your .zip package should contain index.html file in the top level folder structure

Our entry point must be an index.html file that loads our JavaScript files. Parcel is a web application bundler that works with a html file as entry point. It requires almost no configuration. It seems to fit our needs so let's give it a try.

Firstly, we install this new development dependency in our project.

Development server

npm install --dev parcel-bundler
Enter fullscreen mode Exit fullscreen mode

As explained in the getting started section of the documentation, the default command of the cli launchs a development server. It will rebuild our game each time we change a file and refresh the JavaScript code opened in the browser (without reloading the whole page!). We add a dev script to avoid typing this command each time we need it.

  "scripts": {
    "dev": "parcel src/index.html"
  },
Enter fullscreen mode Exit fullscreen mode

Let's create a few files to test it. Here is our folder structure:

.
├── package-lock.json
├── package.json
└── src
    ├── index.html
    └── index.js
Enter fullscreen mode Exit fullscreen mode

Our index.html file import our JavaScript code with a script tag.

<html>
  <body>
    <script src="./index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

To begin we add the well known Hello world!.

console.log('Hello world!')
Enter fullscreen mode Exit fullscreen mode

We start our dev server with the following command:

npm run dev
Enter fullscreen mode Exit fullscreen mode

We should see a log Hello world! in our browser console. I change the message in our console.log parameter with my first name and save the file.

console.log('Hello Yvonnick!')
Enter fullscreen mode Exit fullscreen mode

Our browser has reloaded our code automatically and display the updated log 🎉

Submission file

Our development server is set up. We need to generate our submission file which is a zip file containing our index.html, JavaScript files and other assets.

build

The js13k rules says we can optimize our JavaScript code.

You can use tools that minify JavaScript source code.

Parcel cli has a build command for this purpose. We add a few options to make it fill our needs.

  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html --no-source-maps --experimental-scope-hoisting --public-url ./",
  },
Enter fullscreen mode Exit fullscreen mode

Let's get some explanations about these options.

--public-url option

Parcel prefixes the filename of the bundled javascript file with public-url in the index.html script tag. This option defaults to /. It is fine for a website stored on a static server.

when unzipped should work in the browser.

If we try to open the built index.html we will see a blank page. Because the path of our JavaScript file is /src.9905d997.js. It will look for our JavaScript file at system root. Setting public-url to ./ will fix this issue since it will look for our JavaScript file in the current folder. Now, it works just fine when we open the built index.html.

--no-source-maps option

Source maps are files which reference a readable version of production that are most of the time minified. It helps us tracking bugs in our production bundle. Since our final zip size matters we don't want to include unnecessary files in it so we disable this feature.

--experimental-scope-hoisting option

This option enables tree shaking during the build process. Tree shaking is a feature that prevents unused code of our dependencies being part of our production bundle. You can find out more in this article of Devon Govett.

zip

At last, we add a zip script which creates a zip file with the content from dist folder that is the output of our build command.

  "scripts": {
    "dev": "parcel src/index.html",
    "build": "parcel build src/index.html --no-source-maps --experimental-scope-hoisting --public-url ./",
    "zip": "zip -r submission.zip dist"
  },
Enter fullscreen mode Exit fullscreen mode

Now, we can create our submission file using scripts 👌

Adding a CI/CD

There are two last points to deal with:

  • checking if we reach the 13k limit
  • deploying our game to a public url (it is nice to gather feedback during development)

We don't want to figure out at the end of the competition that our submission file doesn't not fit the requirements. We don't want either to type our commands manually each time we commit some change. Since we need to host our source code on Github we will use GitHub Actions to automate it.

Please provide two sources of your game - first one should be minified and zipped to fit in the 13 kB limit (sent via the form) and the second one should be in a readable form with descriptive variable names and comments (hosted on GitHub).

I wont explain how GitHub Actions works but you can find a lot of nice articles on dev.to on this topic.

Checking our submission file size

First of all, we need to add a script that checks our submission file size. We will use bundlesize to achieve it. It needs a bit of configuration (the file path to test, the max size it must not reach). We add it directly in our package.json file.

"bundlesize": [
  {
    "path": "submission.zip",
    "maxSize": "13 kB"
  }
],
Enter fullscreen mode Exit fullscreen mode

Then, we add a size script that calls bundlesize. It will throw an error if the zip file weight more than 13 kB.

"scripts": {
  // ...
  "size": "bundlesize"
}
Enter fullscreen mode Exit fullscreen mode

We create a first action in the file .github/workflows/ci.yml that will call our freshly created size script with the following content:

name: CI
on:
  pull_request:

jobs:
  size:
    runs-on: ubuntu-latest
    env:
      CI: true

    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: 12
      - run: npm ci
      - run: npm run build
      - run: npm run zip
      - run: npm run size
Enter fullscreen mode Exit fullscreen mode

We trigger this action only on pull request.

on:
  pull_request:
Enter fullscreen mode Exit fullscreen mode

We create the zip file.

      - run: npm ci
      - run: npm run build
      - run: npm run zip
Enter fullscreen mode Exit fullscreen mode

Finally, we run our size script which will prevent us to merge if it fails.

      - run: npm run size
Enter fullscreen mode Exit fullscreen mode

Now, our CI checks for us our submission file size at each commit on pull request.

Deploying our game

Cherry on the cake, we want to deploy our game on a public url so we can share it with friends to gather feedback during development. We create our second action in the file .github/workflows/deploy.yml with the following content:

name: Deploy
on:
  push:
    branches:
      - master
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
        - uses: actions/checkout@v1
        - run: npm ci
        - run: npm run build
        - uses: JamesIves/github-pages-deploy-action@3.5.9
          with:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
            BRANCH: gh-pages # The branch the action should deploy to.
            FOLDER: dist # The folder the action should deploy.
Enter fullscreen mode Exit fullscreen mode

We trigger this action only on master branch.

on:
  push:
    branches:
      - master
Enter fullscreen mode Exit fullscreen mode

We use the action github-pages-deploy-action from James Ives which deploy our code on GitHub Pages. Our app will be available at the url https://[your-handle].github.io/[repository-name] in my case https://frinyvonnick.github.io/js13k-2020.

We are all set 🙌 We can now develop our game at peace!


Follow me on dev.to or twitter if you want to be informed when a new blogpost of this serie is published!

Discussion

pic
Editor guide
Collapse
thomasferro profile image
Thomas Ferro

That's a great workflow :)

One thing that could benefit you is to have the feedback on your development environment. This way, you don't have to wait for your CI to run to know that your bundle is too large !

You could achieve that with a git hook for instance.

Collapse
yvonnickfrin profile image
🦁 Yvonnick FRIN Author

Sure, this is a great idea, thank you 👌