2018-06-16 17:23:02 +00:00
|
|
|
// @flow
|
2017-10-30 14:57:35 +00:00
|
|
|
import { ConcatSource } from 'webpack-sources'
|
2017-06-06 22:32:02 +00:00
|
|
|
import {
|
2018-06-14 17:30:14 +00:00
|
|
|
IS_BUNDLED_PAGE_REGEX,
|
|
|
|
ROUTE_NAME_REGEX
|
2018-06-16 17:23:02 +00:00
|
|
|
} from '../../../lib/constants'
|
2017-06-06 22:32:02 +00:00
|
|
|
|
2017-10-30 14:57:35 +00:00
|
|
|
export default class PagesPlugin {
|
2018-06-16 17:23:02 +00:00
|
|
|
apply (compiler: any) {
|
2018-07-24 09:24:40 +00:00
|
|
|
compiler.hooks.compilation.tap('PagesPlugin', (compilation) => {
|
2018-09-11 18:03:20 +00:00
|
|
|
// This hook is triggered right before a module gets wrapped into it's initializing function,
|
|
|
|
// For example when you look at the source of a bundle you'll see an object holding `'pages/_app.js': function(module, etc, etc)`
|
|
|
|
// This hook triggers right before that code is added and wraps the module into `__NEXT_REGISTER_PAGE` when the module is a page
|
|
|
|
// The reason we're doing this is that we don't want to execute the page code which has potential side effects before switching to a route
|
|
|
|
compilation.moduleTemplates.javascript.hooks.render.tap('PagesPluginRenderPageRegister', (moduleSourcePostModule, module, options) => {
|
|
|
|
const {chunk} = options
|
|
|
|
|
|
|
|
// check if the current module is the entry module, we only want to wrap the topmost module
|
|
|
|
if (chunk.entryModule !== module) {
|
|
|
|
return moduleSourcePostModule
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the chunk is a page
|
2018-07-24 09:24:40 +00:00
|
|
|
if (!IS_BUNDLED_PAGE_REGEX.test(chunk.name)) {
|
2018-09-11 18:03:20 +00:00
|
|
|
return moduleSourcePostModule
|
2018-07-24 09:24:40 +00:00
|
|
|
}
|
|
|
|
|
2018-09-11 18:03:20 +00:00
|
|
|
// Match the route the chunk belongs to
|
2018-07-24 09:24:40 +00:00
|
|
|
let routeName = ROUTE_NAME_REGEX.exec(chunk.name)[1]
|
|
|
|
|
|
|
|
// We need to convert \ into / when we are in windows
|
|
|
|
// to get the proper route name
|
|
|
|
// Here we need to do windows check because it's possible
|
|
|
|
// to have "\" in the filename in unix.
|
|
|
|
// Anyway if someone did that, he'll be having issues here.
|
|
|
|
// But that's something we cannot avoid.
|
|
|
|
if (/^win/.test(process.platform)) {
|
|
|
|
routeName = routeName.replace(/\\/g, '/')
|
|
|
|
}
|
|
|
|
|
|
|
|
routeName = `/${routeName.replace(/(^|\/)index$/, '')}`
|
|
|
|
|
2018-09-11 18:03:20 +00:00
|
|
|
const source = new ConcatSource(
|
|
|
|
`__NEXT_REGISTER_PAGE('${routeName}', function() {\n`,
|
|
|
|
moduleSourcePostModule,
|
|
|
|
'\nreturn { page: module.exports.default }',
|
|
|
|
'});'
|
|
|
|
)
|
2018-07-24 09:24:40 +00:00
|
|
|
|
|
|
|
return source
|
|
|
|
})
|
2017-04-18 04:18:43 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|