Dzulqarnain Nasir

  • January 14, 2019

    Webpack-ing static content for TypeScript

    Here’s a quick one.

    I’ve recently started cleaning up the code for one of my projects, and one of the things I did was introducing the file-loader plugin, and converting static content references throughout my codebase.

    It was a pretty straightforward process for image URLs within my Vue files, but then I also have code that switches out the background image of elements based on specific conditions. This requires the static content URL to be imported into the code that handles the logic.

    For example:

    // component class
    
    get centerOverlayStyle() {
        let backgroundImage = null;
    
        if (this.inputMode === MapInputMode.PICKUP) backgroundImage = 'url(/public/static/pickup-icon.svg)';
        if (this.inputMode === MapInputMode.DROPOFF) backgroundImage = 'url(/public/static/dropoff-icon.svg)';
    
        return { backgroundImage };
    }
    

    In order for me to use the image files emitted by file-loader, I need to replace the image paths with the ones generated by the plugin.

    According to the documentation, I can simply import the image file into my code, and assign it to a local variable, and use it whenever I need reference to the image URL anywhere in my code. file-loader would resolve the path, allowing my code to point to the correct URL.

    import pickupIcon from '@/static/pickup-icon.svg';
    import dropoffIcon from '@/static/dropoff-icon.svg';
    
    // component class
    
    get centerOverlayStyle() {
        let backgroundImage = null;
    
        if (this.inputMode === MapInputMode.PICKUP) backgroundImage = `url(${pickupIcon})`;
        if (this.inputMode === MapInputMode.DROPOFF) backgroundImage = `url(${dropoffIcon})`;
    
        return { backgroundImage };
    }
    

    Unfortunately, while this works for regular JavaScript, TypeScript sees this as a problem.

    Cannot find module '@/static/pickup-icon.svg'.
    Cannot find module '@/static/dropoff-icon.svg'.
    

    TypeScript assumes that everything we import are modules, and if it cannot determine this to be the case, it will log an error. The definition of a module can either be determined by the imported TypeScript (.ts/.tsx) file, or by a type declaration file (.d.ts) that the code depends on. [Reference]

    So, the solution is quite simple. We just have to tell TypeScript about our image files by adding a type declaration file (d.ts.), and declare the image files we’re using in our project as a module.

    // images.d.ts
    
    declare module '*.svg';
    // duplicate for other image file extensions
    

    Et voilà. Problem solved.

  • December 10, 2018

    IoC in JavaScript with InversifyJS

    In C#, interfaces are used to set up a definition that classes can implement. Any class that implements an interface must adhere to the definition declared by the interface.

    Think of them as a sort of menu you’d find at a typical pizzeria. The menu says they serve Margherita pizza.

    Then you have the classes that implement the interfaces - i.e. the cooks that prepare the pizza mentioned in the menu.

    The pizzeria may have multiple cooks, and the cooks may differ in the way they prepare the dish - i.e. one cook may use more cheese, and another may use less salt in the dough. Regardless, the resulting product will still be served as Margherita pizza.

    Similarly, the consumers of your modules should only be made aware of the “menu”, without having to worry about how the pizza is prepared. This way, you can swap out the “cook” whenever you want, without the consumers being any the wiser.

    This is something I’ve been taking for granted in .NET development, and while there have been some efforts in bringing this concept to JavaScript, the implementation has not been that great - until now.

    Read more »
  • November 26, 2018

    Is Yarn still faster than NPM in late 2018?

    If you’re like me, chances are you’ve heard about Yarn, an alternative to the Node Package Manager (NPM). You may have even heard how much faster it is compared to NPM.

    The dust has settled since Yarn first entered the scene, and NPM has punched back with quite a few updates. So it’s time to see if anything has changed.

    Read more »
  • November 24, 2018

    How To Auto-publish GitHub Pages Using Azure Functions

    If you’re reading this, and it’s past 24th November 2018 at 10:00 EET, it means my small experiment worked.

    As you have probably noticed, I’ve moved away from Wordpress to GitHub Pages, which runs on Jekyll, a static site generator. The one thing I miss from my Wordpress days is the ability to schedule publishing new posts.

    GitHub Pages requires you to manually add posts to the master branch of the repository, which means that if I wanted to publish the post I wrote last night at 9am the next morning, I would have to physically push or merge said post to the repository at 9am the next morning. Needless to say, this is far from ideal.

    So I decided to use Azure Functions to call GitHub’s API to instruct it to build my GitHub Pages project, which should automatically publish my posts based on their publish time.

    Read more »
  • November 06, 2018

    Smart Bundle Management Using JavaScript Modules

    I recently read an article on SmashingMagazine on managing bundles for modern and legacy browsers, in which the author had discovered that bundles built for legacy browsers are, on average, 25% larger than those created for modern browsers.

    This is mainly due to the fact that native support for ES6 has resulted in the possibility to achieve the same results with less code. Unfortunately, legacy browsers such as Internet Explorer lack support for most, if not all, of ES6, forcing developers to include workarounds and polyfills just to get things working, resulting in larger bundle files.

    In the article, the author suggested creating separate bundles for each platform, and employing server-side browser sniffing to serve the appropriate bundle to users.

    While this method works, there are numerous reasons why browser sniffing is bad.

    Read more »