最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do import and use a TypeScript class from a module on my HTML page? - Stack Overflow

programmeradmin3浏览0评论

This seems like something so elementary, but I've wasted so much time struggling with it. I've gone through dozens of different resources, documents, and Stack Overflow questions, and if the answers I need were in there I missed them among the plethora of stated solutions that didn't work. Any help will be very much appreciated. :)

So I've got a class in TypeScript. My goal is to be able to, in a script tag on an HTML page, create an instance of that class and call a function on it. For the sake of relevance, we'll keep it simple:

import { MyDependency } from ...

export default class MyClass {
  constructor(...) {
     ...
  }

  doSomething() {
     var example = new MyDependency()
  }
}

In actuality, there's many classes, in many files, which have dependencies on both one another and a variety of NPM packages. Through some convoluted methods that I'm looking to replace by asking this question, I know this code runs and can be executed in the browser. Just in case it's relevant, here's my tsconfig anyway:

{
  "compilerOptions": {
    ...
    "sourceMap": true,
    "target": "ES2017",
    "moduleResolution": "Node",
    "module": "UMD",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "lib": [ "esnext", "dom" ]
  }
  ...
}

We're running webpack on this stuff. The webpack config looks like so:

module.exports = {
    entry: {
        "my-class": path.resolve(__dirname, "./ts/my-directory/my-class.ts"),
        "my-dependency": path.resolve(__dirname, "./ts/my-directory/my-dependency.ts")
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: "ts-loader"
            },
            {
                test: /\.m?js/,
                resolve: {
                    fullySpecified: false,
                },
            }
        ],
    },
    resolve: {
        alias: {
            'node_modules': "/node_modules"
        },
        extensions: [".tsx", ".ts", ".js", ".css"]
    },
    output: {
        filename: "[name].js",
        libraryTarget: "umd",
        library: "MyLibrary",
        libraryExport: "default",
        path: path.resolve(__dirname, "dist")
    },
};

Running webpack with this will successfully generate a my-class.js file.

Lastly, one example of an attempt to invoke this on a page:

<Script src="/dist/my-class.js"></Script>

<script type="module">
        var instance = new window.MyLibrary.MyClass()
        instance.doSomething()
</script>

This particular attempt is failing with a message that it cannot find the module for MyDependency, which is frankly further than most permutations have gotten. I've messed around with import, import(), require(), expose-loader, and various other things; usually I'm told either the my-class module does not exist, or that it does not contain an export called MyClass (which the generated my-class.js clearly does, so I guess the module wasn't loading correctly?).

Any recommendations, again, will be much appreciated!

This seems like something so elementary, but I've wasted so much time struggling with it. I've gone through dozens of different resources, documents, and Stack Overflow questions, and if the answers I need were in there I missed them among the plethora of stated solutions that didn't work. Any help will be very much appreciated. :)

So I've got a class in TypeScript. My goal is to be able to, in a script tag on an HTML page, create an instance of that class and call a function on it. For the sake of relevance, we'll keep it simple:

import { MyDependency } from ...

export default class MyClass {
  constructor(...) {
     ...
  }

  doSomething() {
     var example = new MyDependency()
  }
}

In actuality, there's many classes, in many files, which have dependencies on both one another and a variety of NPM packages. Through some convoluted methods that I'm looking to replace by asking this question, I know this code runs and can be executed in the browser. Just in case it's relevant, here's my tsconfig anyway:

{
  "compilerOptions": {
    ...
    "sourceMap": true,
    "target": "ES2017",
    "moduleResolution": "Node",
    "module": "UMD",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "lib": [ "esnext", "dom" ]
  }
  ...
}

We're running webpack on this stuff. The webpack config looks like so:

module.exports = {
    entry: {
        "my-class": path.resolve(__dirname, "./ts/my-directory/my-class.ts"),
        "my-dependency": path.resolve(__dirname, "./ts/my-directory/my-dependency.ts")
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: "ts-loader"
            },
            {
                test: /\.m?js/,
                resolve: {
                    fullySpecified: false,
                },
            }
        ],
    },
    resolve: {
        alias: {
            'node_modules': "/node_modules"
        },
        extensions: [".tsx", ".ts", ".js", ".css"]
    },
    output: {
        filename: "[name].js",
        libraryTarget: "umd",
        library: "MyLibrary",
        libraryExport: "default",
        path: path.resolve(__dirname, "dist")
    },
};

Running webpack with this will successfully generate a my-class.js file.

Lastly, one example of an attempt to invoke this on a page:

<Script src="/dist/my-class.js"></Script>

<script type="module">
        var instance = new window.MyLibrary.MyClass()
        instance.doSomething()
</script>

This particular attempt is failing with a message that it cannot find the module for MyDependency, which is frankly further than most permutations have gotten. I've messed around with import, import(), require(), expose-loader, and various other things; usually I'm told either the my-class module does not exist, or that it does not contain an export called MyClass (which the generated my-class.js clearly does, so I guess the module wasn't loading correctly?).

Any recommendations, again, will be much appreciated!

Share Improve this question asked Feb 7 at 16:58 yvseanyvsean 392 bronze badges 2
  • "This seems like something so elementary" it should be. It isn't. Don't feel bad for struggling. – Jared Smith Commented Feb 7 at 17:22
  • Why do you use <script type="module"> if you don't go for import { MyClass } from /dist/my-class.js"; (or import * as MyLibrary from /dist/my-class.js"; or some similar import declaration)? – Bergi Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default -2

It looks like the issue is with how Webpack is bundling your TypeScript class. To fix it:

Update webpack.config.js to correctly expose MyLibrary:

output: {
  filename: '[name].js',
  path: path.resolve(__dirname, 'dist'),
  library: {
    name: 'MyLibrary',
    type: 'umd',
  },
}

In your HTML file, access it as:

const instance = new MyLibrary.MyClass();
instance.doSomething();

Make sure the script path in your HTML is correct. This should resolve the issue!

发布评论

评论列表(0)

  1. 暂无评论