@@ -4,6 +4,8 @@ const Markdoc = require('@markdoc/markdoc');
4
4
5
5
const DEFAULT_SCHEMA_PATH = './markdoc' ;
6
6
7
+ function noop ( ) { }
8
+
7
9
function normalize ( s ) {
8
10
return s . replace ( / \\ / g, path . win32 . sep . repeat ( 2 ) ) ;
9
11
}
@@ -40,7 +42,6 @@ async function gatherPartials(ast, schemaDir) {
40
42
41
43
// Returning a JSX object is what allows fast refresh to work
42
44
async function load ( source ) {
43
- const logger = this . getLogger ( '@markdoc/next.js' ) ;
44
45
// https://webpack.js.org/concepts/module-resolution/
45
46
const resolve = this . getResolve ( {
46
47
// https://webpack.js.org/api/loaders/#thisgetresolve
@@ -52,9 +53,11 @@ async function load(source) {
52
53
dir, // Root directory from Next.js (contains next.config.js)
53
54
mode = 'static' ,
54
55
schemaPath = DEFAULT_SCHEMA_PATH ,
56
+ nextRuntime,
55
57
} = this . getOptions ( ) || { } ;
56
58
57
59
const schemaDir = path . resolve ( dir , schemaPath || DEFAULT_SCHEMA_PATH ) ;
60
+ const ast = Markdoc . parse ( source ) ;
58
61
59
62
// Grabs the path of the file relative to the `/pages` directory
60
63
// to pass into the app props later.
@@ -63,59 +66,87 @@ async function load(source) {
63
66
// https://nextjs.org/docs/advanced-features/src-directory
64
67
const filepath = this . resourcePath . split ( 'pages' ) [ 1 ] ;
65
68
66
- const ast = Markdoc . parse ( source ) ;
69
+ // Only run validation when during client compilation
70
+ if ( ! nextRuntime ) {
71
+ let previousRefreshReg = global . $RefreshReg$ ;
72
+ let previousRefreshSig = global . $RefreshSig$ ;
67
73
68
- const errors = Markdoc . validate ( ast )
69
- // tags are not yet registered, so ignore these errors
70
- . filter ( ( e ) => e . error . id !== 'tag-undefined' )
71
- . filter ( ( e ) => {
72
- switch ( e . error . level ) {
73
- case 'debug' :
74
- case 'error' :
75
- case 'info' : {
76
- logger [ e . error . level ] ( e . error . message ) ;
77
- break ;
78
- }
79
- case 'warning' : {
80
- logger . warn ( e . error . message ) ;
81
- break ;
82
- }
83
- case 'critical' : {
84
- logger . error ( e . error . message ) ;
85
- break ;
74
+ // https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/176#issuecomment-683150213
75
+ global . $RefreshReg$ = noop ;
76
+ global . $RefreshSig$ = ( ) => noop ;
77
+
78
+ // This imports the config as an in-memory object
79
+ const importAtBuildTime = async ( resource ) => {
80
+ try {
81
+ const object = await this . importModule (
82
+ await resolve ( schemaDir , resource )
83
+ ) ;
84
+ return object ? object . default || object : { } ;
85
+ } catch ( error ) {
86
+ return undefined ;
87
+ }
88
+ } ;
89
+
90
+ const cfg = {
91
+ tags : await importAtBuildTime ( 'tags' ) ,
92
+ nodes : await importAtBuildTime ( 'nodes' ) ,
93
+ functions : await importAtBuildTime ( 'functions' ) ,
94
+ ...( await importAtBuildTime ( 'config' ) ) ,
95
+ } ;
96
+
97
+ const errors = Markdoc . validate ( ast , cfg )
98
+ . filter ( ( e ) => {
99
+ switch ( e . error . level ) {
100
+ case 'debug' :
101
+ case 'error' :
102
+ case 'info' : {
103
+ console [ e . error . level ] ( e . error . message ) ;
104
+ break ;
105
+ }
106
+ case 'warning' : {
107
+ console . warn ( e . error . message ) ;
108
+ break ;
109
+ }
110
+ case 'critical' : {
111
+ console . error ( e . error . message ) ;
112
+ break ;
113
+ }
114
+ default : {
115
+ console . log ( e . error . message ) ;
116
+ break ;
117
+ }
86
118
}
87
- default : {
88
- logger . log ( e . error . message ) ;
89
- break ;
119
+ return e . error . level === 'critical' ;
120
+ } )
121
+ . flatMap ( ( e ) => {
122
+ const lines = source . split ( '\n' ) ;
123
+
124
+ const message = [ e . error . message , ...lines . slice ( ...e . lines ) ] ;
125
+
126
+ if (
127
+ e . error &&
128
+ e . error . location &&
129
+ e . error . location . start &&
130
+ e . error . location . start . offset
131
+ ) {
132
+ const prev = lines . slice ( 0 , e . lines [ 0 ] ) . join ( '\n' ) . length ;
133
+ const diff = e . error . location . start . offset - prev ;
134
+
135
+ const pointer = `${ ' ' . repeat ( diff ) } ^` ;
136
+ message . push ( pointer ) ;
90
137
}
91
- }
92
- return e . error . level === 'critical' ;
93
- } )
94
- . flatMap ( ( e ) => {
95
- const lines = source . split ( '\n' ) ;
96
-
97
- const message = [ e . error . message , ...lines . slice ( ...e . lines ) ] ;
98
-
99
- if (
100
- e . error &&
101
- e . error . location &&
102
- e . error . location . start &&
103
- e . error . location . start . offset
104
- ) {
105
- const prev = lines . slice ( 0 , e . lines [ 0 ] ) . join ( '\n' ) . length ;
106
- const diff = e . error . location . start . offset - prev ;
107
-
108
- const pointer = `${ ' ' . repeat ( diff ) } ^` ;
109
- message . push ( pointer ) ;
110
- }
111
138
112
- // add extra newline between errors
113
- message . push ( '' ) ;
114
- return message ;
115
- } ) ;
139
+ // add extra newline between errors
140
+ message . push ( '' ) ;
141
+ return message ;
142
+ } ) ;
143
+
144
+ if ( errors . length ) {
145
+ throw new Error ( errors . join ( '\n' ) ) ;
146
+ }
116
147
117
- if ( errors . length ) {
118
- throw new Error ( errors . join ( '\n' ) ) ;
148
+ global . $RefreshReg$ = previousRefreshReg ;
149
+ global . $RefreshSig$ = previousRefreshSig ;
119
150
}
120
151
121
152
const partials = await gatherPartials . call (
@@ -132,7 +163,8 @@ async function load(source) {
132
163
try {
133
164
const directoryExists = await fs . promises . stat ( schemaDir ) ;
134
165
135
- async function readDir ( variable ) {
166
+ // This creates import strings that cause the config to be imported runtime
167
+ async function importAtRuntime ( variable ) {
136
168
try {
137
169
const module = await resolve ( schemaDir , variable ) ;
138
170
return `import * as ${ variable } from '${ normalize ( module ) } '` ;
@@ -143,10 +175,10 @@ async function load(source) {
143
175
144
176
if ( directoryExists ) {
145
177
schemaCode = `
146
- ${ await readDir ( 'config' ) }
147
- ${ await readDir ( 'tags' ) }
148
- ${ await readDir ( 'nodes' ) }
149
- ${ await readDir ( 'functions' ) }
178
+ ${ await importAtRuntime ( 'config' ) }
179
+ ${ await importAtRuntime ( 'tags' ) }
180
+ ${ await importAtRuntime ( 'nodes' ) }
181
+ ${ await importAtRuntime ( 'functions' ) }
150
182
const schema = {
151
183
tags: tags ? (tags.default || tags) : {},
152
184
nodes: nodes ? (nodes.default || nodes) : {},
0 commit comments