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?