skip to Main Content

I’m working on some Typescript project which the output (JS) will be used in a Javascript project (like a plugin). Like this:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <script src="../dist/bundled.js"></script>
        <script>
            new TheClass()
        </script>
    </body>
</html>

TheClass is defined in the Typescript file which is converted to Javascript (bundled.js) by Webpack. The target in the tsconfig.js is ES5 and the module item is set to ES6.

Now, it throws this error: Uncaught ReferenceError: TheClass is not defined.

So, I tried to add library options to the output section of webpack.config.js:

const path = require("path")

module.exports = {
    mode: "development",
    entry: "./src/main.ts",
    devtool: "inline-source-map",
    module: {
        rules: [
            {
                test: /.tsx?$/,
                include: path.resolve(__dirname, "src"),
                use: "ts-loader",
                exclude: /node_modules/,
            },
        ],
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"],
    },
    output: {
        libraryTarget: 'umd', ///////////////////////////////// added this.
        library: 'MyLibrary', ///////////////////////////////// added this.
        filename: "bundled.js",
        path: path.resolve(__dirname, "dist"),
    },
}

Now I can access the class like this:

new MyLibrary.TheClass()

I also need to mention that the class is defined like this (it is exported):

export class TheClass {}

Ok, now there 3 questions:

  1. Is there another way for doing this?
  2. How can I access the class like: TheClass() (And not MyLibrary.TheClass())
  3. How does libraryTarget: 'umd' help?

I also tried export default:

export default class TheClass {}

So, I can use the class like:

new MyLibrary()

It didn’t work.

2

Answers


  1. Chosen as BEST ANSWER

    Found it! I changed this:

    libraryTarget: 'umd',
    library: 'MyLibrary',
    

    Into this:

    libraryExport: 'default',
    library: 'TheClass',
    

    I also used export default in my Typescript file:

    export default class TheClass {}
    

    Now, I can do what I wanted to:

    new TheClass()
    

    Although, logically speaking, the name of our library has to be the same with the name of our class. So, if you change your class name, remember to change the library's name too.


    If anyone knows how to prevent this conflict between the library and the class name, please comment on this answer or message me. Thanks.


  2. Good question. Here are answers on each question based on what I know:

    Is there another way for doing this?

    No, I think this is the only way to export your module code to an external library.

    How can I access the class like: TheClass() (And not MyLibrary.TheClass())

    You can check out the type either window or global as addressed here https://webpack.js.org/configuration/output/#type-window which is likely to work for your case:

    library: {
       name: 'TheClass',
       type: 'window', // or `global`
    },
    

    How does libraryTarget: ‘umd’ help?

    umd is an proposed module which is designed to work for many environments such as browser and node so it should work on as module on both envs

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search