rsnext/packages/next/build/webpack/loaders/next-plugin-loader.ts
Tim Neutkens 7c80febcf7 Initial plugins implementation (#9139)
* Add initial bit for plugins

* Add checks for needed metadata values

* Add test

* Initial plugins changes

* Add handling for _app middleware

* Add loading of _document middleware and
handling of multiple default export syntaxes

* Fix insert order for middleware member expression

* Remove early return from middleware plugin from testing

* Add tests for current plugin middlewares

* Update test plugin package.json

* Update handling for class default export

* Update to use webpack loader instead of babel
plugin, remove redundant middleware naming, and add field for required env for plugins

* Add middleware to support material-ui use case
and example material-ui plugin

* Update tests and remove tests stuff from google analytics plugin

* Remove old plugin suite

* Add init-server middleware

* Exit hard without stack trace when error in collecting plugins

* Add on-error-client and on-error-server and update
to run init-server with next-start in serverless mode

* Update init-client for google analytics plugin

* Add example Sentry plugin and update with-sentry-simple

* Remove middleware field/folder and use src dir for plugins

* Add post-hydration middleware and update
material-ui plugin

* Put plugins code behind flag

* Update chromedriver

* Revert "Update chromedriver"

This reverts commit 1461e978e677f7da05e29e0415ec614a04bf65f9.

* Update lock file

* Remove un-needed _app for sentry example

* Add auto loading of scoped packages, add plugins
config for manually listing plugins, and update
to only collect plugins once

* Update example plugins

* Expose plugins' config

* Rename plugin lifecycles and add babel-preset-build

* Rename other methods with unstable

* Update log when plugin config overrides auto-detecting
2019-11-01 14:13:13 -05:00

44 lines
1.2 KiB
TypeScript

import { loader } from 'webpack'
import { parse } from 'querystring'
import { PluginMetaData, getPluginId } from '../../plugins/collect-plugins'
export type NextPluginLoaderQuery = {
middleware: string
}
export const pluginLoaderOptions: {
plugins: PluginMetaData[]
} = {
plugins: [],
}
const nextPluginLoader: loader.Loader = function(source) {
const { middleware }: NextPluginLoaderQuery =
typeof this.query === 'string' ? parse(this.query.substr(1)) : this.query
const plugins = pluginLoaderOptions.plugins.filter(plugin => {
return plugin.middleware.includes(middleware)
})
const pluginIds: string[] = []
const pluginConfigs: any[] = []
return `
${plugins
.map(plugin => {
const pluginId = getPluginId(plugin.pkgName)
pluginIds.push(pluginId)
pluginConfigs.push(plugin.config || {})
return `import ${pluginId} from '${plugin.directory}/src/${middleware}'`
})
.join('\n')}
export default function (ctx) {
return Promise.all([${pluginIds
.map((id, idx) => `${id}(ctx, ${JSON.stringify(pluginConfigs[idx])})`)
.join(',')}])
}
`
}
export default nextPluginLoader