简体   繁体   中英

Uncaught ReferenceError: foo is not defined when using TypeScript + Webpack

My Chrome extension works fine if I just use JavaScript.

When I tried for TypeScript + Webpack, the issue I was facing was that the function foo was not found.

Uncaught ReferenceError: foo is not defined

manifest.json:

    "content_scripts":
    [
        {
            "js": ["global.js", "content.js"],
            "matches": ["https://*.my-domain.com/*"],
            "run_at": "document_end"
        }
    ],

content.ts:

console.log("content.js");

let afterDOMLoaded = () =>
{
    foo()
    .then((result) => console.log(result))
    .catch((error) => console.error(error));
}

if (document.readyState === 'loading')
{
    document.addEventListener('DOMContentLoaded', afterDOMLoaded);
}
else
{
    afterDOMLoaded();
}

global.js:

console.log("global.js");

let foo = async () =>
{
    await something();
}

tsconfig.json:

{
    "compilerOptions": {
        "outDir": "./dist",
        "allowJs": true,
        "target": "ES6"
    },
    "include": [
        "./src/**/*"
    ]
}

webpack.config.js:

const path = require("path");
const glob = require("glob");
const CopyPlugin = require("copy-webpack-plugin");

module.exports =
{
    entry: glob.sync('./src/**/*.ts').reduce(function(obj, el)
    {
        obj[path.parse(el).name] = el;
        return obj;
    }, {}),

    output:
    {
        filename: "[name].js",
        path: path.resolve(__dirname, "dist")
    },

    module:
    {
        rules: [
            { test: /\.ts?$/, loader: "ts-loader" }
        ]
    },

    plugins: [
        new CopyPlugin(
        {
            patterns: [
            {
                from: "**",
                to: path.resolve(__dirname, "dist"),
                context: path.resolve(__dirname, "src"),
                globOptions: { ignore: ["**/*.ts"] },
                force: true
            }]
        })
    ],
    
    optimization:
    {
        minimize: false,
        splitChunks: 
        {
            chunks: "all"
        }
    }
}

I can see that the ordering of loading the scripts is also correct as console.log shows:

global.js
content.js

If I define foo in content.ts, right on top, then everything works.

So I don't know where the issue is, webpack or typescript?

Webpack wraps each "module" (a file is itself a module) in its own function scope, so the let foo variable is block scoped and no longer accessible in "global" scope by the content module.

Use export / import syntax (after all, that is very probably a reason for using a bundler), or place it on global scope (no variable keyword). But IIRC, using global scope in an extension may interfere with the rendered web pages?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM