Is it possible to preload dynamic module imported via dynamic import in Webpack (Next.js)?

Viewed 16

Let's say that I have private npm package called '@plugin/test-plugin' which is added to dependencies in package.json of Next.js app. Then, I import it using dynamic import like so:

// [next.js app]/pages/index.tsx
import('@plugin/test-plugin');
// [next.js app]/package.json
...
"dependencies": {
    ...
    "@plugin/test-plugin": "0.0.0"
}
...

That works fine, webpack can handle it and I can see exported module.

But my goal here is to make this plugin name dynamic from array (every plugin will be added in dependencies in package.json):

// [next.js app]/pages/index.tsx
const data = [
    'test-plugin'
]

const pluginImports = data.map(n => import(`@plugin/${n}`))

Webpack finds the plugin but has a problem with loading it - it stops on plugin's index.d.ts giving following error:

app: error - ../plugins/test-plugin/lib/cjs/index.d.ts
app: Module parse failed: Unexpected token (2:8)
app: You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
app: | /// <reference types="react" />
app: > declare const linkDatabasePlugin: {
app: |     component: () => JSX.Element;
app: |     meta: {

@plugin/test-plugin has only one file "index.tsx" for testing:

// [@plugin/test-plugin]/src/index.tsx
import React from "react";

const A = () => {
    return <div>Test</div>
}

const linkDatabasePlugin = {
    component: A,
    meta: {
        name: "Test Plugin Interface"
    }
}

export { linkDatabasePlugin as DATABASE_PLUGIN_MANIFEST };

Plugin is built using native typescript with following tsconfig.json with command tsc && tsc --module commonjs --outDir lib/cjs:

{
    "compilerOptions": {
        "outDir": "lib/esm",
        "module": "esnext",
        "target": "es5",
        "lib": [
            "es6",
            "dom",
            "es2016",
            "es2017"
        ],
        "jsx": "react",
        "declaration": true,
        "moduleResolution": "node",
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "esModuleInterop": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "suppressImplicitAnyIndexErrors": true,
        "allowSyntheticDefaultImports": true
    },
    "include": [
        "src"
    ],
    "exclude": [
        "node_modules",
        "lib"
    ]
}

As an output I'm getting built library as so:

- lib
--- cjs
------ index.d.ts
------ index.js
--- esm
------ index.d.ts
------ index.js

So the real problem is that Webpack doesn't know how to handle those files in runtime. Is there any way to tell webpack to preload some modules from 'node_modules' in webpack.config for the Next.js app? Plugins and Next.js app are in monorepo and plugins are shared to Next.js app using Lerna. Everything works if I type static names, but it isn't an option for future app grow.

I will always know what plugins to load (plugin names are static during runtime).

I've made research of my own and I haven't found solution for this type of case. Maybe webpack has some functions which will allow me to preload those modules that I'm not aware of.

Is there a solution or any workaround?

0 Answers
Related