@startupjs/bundler 0.60.0-canary.1 → 0.60.0-canary.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  // TODO: add support for source maps
2
2
  const babel = require('@babel/core')
3
- const { isStartupjsPluginEcosystemFile, CONFIG_FILENAME_REGEX } = require('./utils')
3
+ const { isStartupjsPluginEcosystemFile, CONFIG_FILENAME_REGEX } = require('babel-preset-startupjs/utils')
4
4
 
5
5
  const PLUGIN_KEYS = ['name', 'for', 'order', 'enabled']
6
6
  const PROJECT_KEYS = ['plugins', 'modules']
@@ -20,7 +20,7 @@ module.exports = function eliminatorLoader (source) {
20
20
  if (!(
21
21
  isStartupjsPluginEcosystemFile(filename) ||
22
22
  (clientModel && isModelFile(filename, source))
23
- )) return source
23
+ )) return source // source inside Program is state.file.code
24
24
 
25
25
  const envs = this.query.envs
26
26
  if (!envs) throw Error("eliminatorLoader: envs not provided (for example ['features', 'isomorphic', 'client'])")
@@ -0,0 +1,18 @@
1
+ const remarkGfm = require('remark-gfm').default
2
+ const { compileSync } = require('@mdx-js/mdx')
3
+
4
+ module.exports = function getMDXLoader (source) {
5
+ try {
6
+ source = compileSync(source, {
7
+ providerImportSource: '@startupjs/mdx/useMDXComponents',
8
+ remarkPlugins: [remarkGfm],
9
+ jsx: true
10
+ }).value
11
+ } catch (err) {
12
+ if (err) {
13
+ console.log('>> mdx compile error', err)
14
+ throw err
15
+ }
16
+ }
17
+ return source
18
+ }
@@ -15,7 +15,10 @@ module.exports = function startupjsLoader (source) {
15
15
  configFile: false,
16
16
  presets: [
17
17
  [require('babel-preset-startupjs'), {
18
+ // in Program: state.file.opts.caller.platform when used in metro
19
+ // when used in metro - state.file.opts.caller.bundler === 'metro'
18
20
  platform,
21
+ // in Program: state.file.opts.envName when used in metro
19
22
  env
20
23
  }],
21
24
  [require('cssxjs/babel'), { platform }]
@@ -1,11 +1,9 @@
1
1
  const stylusToCssLoader = require('cssxjs/loaders/stylusToCssLoader')
2
2
  const cssToReactNativeLoader = require('cssxjs/loaders/cssToReactNativeLoader')
3
3
  const mdxExamplesLoader = require('./lib/mdxExamplesLoader')
4
- const getMDXLoader = require('./lib/getMDXLoader')
5
- const eliminatorLoader = require('./lib/eliminatorLoader')
4
+ const mdxLoader = require('./lib/mdxLoader')
6
5
  const callLoader = require('./lib/callLoader')
7
6
  const asyncSvgLoader = require('./lib/asyncSvgLoader')
8
- const startupjsLoader = require('./lib/startupjsLoader')
9
7
 
10
8
  module.exports.transform = async function startupjsMetroBabelTransform ({
11
9
  src, filename, options: { upstreamTransformer, ...options } = {}
@@ -22,23 +20,10 @@ module.exports.transform = async function startupjsMetroBabelTransform ({
22
20
  } else if (/\.svg$/.test(filename)) {
23
21
  src = await callLoader(asyncSvgLoader, src, filename)
24
22
  } else if (/\.mdx?$/.test(filename)) {
25
- const mdxLoader = await getMDXLoader()
26
23
  src = callLoader(mdxExamplesLoader, src, filename)
27
24
  src = callLoader(mdxLoader, src, filename)
28
25
  }
29
26
 
30
- // js transformations
31
- if (/\.[mc]?[jt]sx?$/.test(filename)) {
32
- src = callLoader(eliminatorLoader, src, filename, {
33
- envs: ['features', 'isomorphic', 'client'],
34
- useRequireContext: true,
35
- clientModel: true
36
- })
37
- }
38
- if ((/\.mdx?$/.test(filename) || /\.[mc]?[jt]sx?$/.test(filename)) && /['"](?:startupjs)['"]/.test(src)) {
39
- src = callLoader(startupjsLoader, src, filename, { platform })
40
- }
41
-
42
27
  return upstreamTransformer.transform({ src, filename, options })
43
28
  }
44
29
 
package/metro-config.js CHANGED
@@ -5,11 +5,15 @@ const { join, resolve } = require('path')
5
5
 
6
6
  // To pass existing config for modification, pass it as 'upstreamConfig' in options:
7
7
  // config = getDefaultConfig(__dirname, { upstreamConfig })
8
- exports.getDefaultConfig = function getDefaultConfig (projectRoot, { upstreamConfig } = {}) {
8
+ exports.getDefaultConfig = function getDefaultConfig (projectRoot, {
9
+ upstreamConfig,
10
+ checkStartupjsBabel = true
11
+ } = {}) {
9
12
  let packageJson = {}
10
13
  try {
11
14
  packageJson = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'))
12
15
  } catch (err) {}
16
+ if (checkStartupjsBabel) _checkStartupjsBabel(projectRoot)
13
17
  const features = getFeatures(projectRoot)
14
18
  upstreamConfig ??= getUpstreamConfig(projectRoot)
15
19
  const isExpo = checkIfExpo(upstreamConfig)
@@ -44,7 +48,12 @@ exports.getDefaultConfig = function getDefaultConfig (projectRoot, { upstreamCon
44
48
  }
45
49
 
46
50
  function isBuild () {
47
- return process.env.IS_BUILD || process.env.CI || process.env.EAS_BUILD
51
+ return (
52
+ process.env.IS_BUILD ||
53
+ process.env.CI ||
54
+ process.env.EAS_BUILD ||
55
+ (process.env.NODE_ENV === 'production' && !process.env.FORCE_SERVER)
56
+ )
48
57
  }
49
58
 
50
59
  function addServer (config) {
@@ -143,3 +152,36 @@ function getMonorepoRootPackageJson (projectRoot) {
143
152
  } catch (err) {}
144
153
  }
145
154
  }
155
+
156
+ function _checkStartupjsBabel (projectRoot) {
157
+ const babelConfigPath = join(projectRoot, 'babel.config.cjs')
158
+ if (!existsSync(babelConfigPath)) {
159
+ console.error('ERROR:', ERRORS.missingBabelConfig)
160
+ throw Error(ERRORS.missingBabelConfig)
161
+ }
162
+ const babelConfig = readFileSync(join(projectRoot, 'babel.config.cjs'), 'utf8')
163
+ if (!babelConfig.includes('startupjs/babel')) {
164
+ console.error('ERROR:', ERRORS.noStartupjsBabelPreset)
165
+ throw Error(ERRORS.noStartupjsBabelPreset)
166
+ }
167
+ }
168
+
169
+ const ERRORS = {
170
+ missingBabelConfig: `
171
+ Missing babel.config.cjs with 'startupjs/babel' preset.
172
+ Please create babel.config.cjs following the instructions from Expo (or pure React Native) documentation,
173
+ and add 'startupjs/babel' as the LAST item in the 'presets' array.
174
+
175
+ To ignore this error (if you want to use a custom babel preset to transform startupjs code),
176
+ you can pass the option 'checkStartupjsBabel: false'
177
+ when calling 'getDefaultConfig(projectRoot, options)' from 'metro.config.cjs'.
178
+ `,
179
+ noStartupjsBabelPreset: `
180
+ Your babel.config.cjs is missing 'startupjs/babel' preset.
181
+ Please add 'startupjs/babel' as the LAST item in the 'presets' array of your babel.config.cjs.
182
+
183
+ To ignore this error (if you want to use a custom babel preset to transform startupjs code),
184
+ you can pass the option 'checkStartupjsBabel: false'
185
+ when calling 'getDefaultConfig(projectRoot, options)' from 'metro.config.cjs'.
186
+ `
187
+ }
package/nodeLoader.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { readFile } from 'node:fs/promises'
2
2
  import { fileURLToPath } from 'node:url'
3
+ import { isStartupjsPluginEcosystemFile } from 'babel-preset-startupjs/utils'
3
4
  import callLoader from './lib/callLoader.js'
4
5
  import yamlLoader from './lib/yamlLoader.js'
5
6
  import eliminatorLoader from './lib/eliminatorLoader.js'
6
- import { isStartupjsPluginEcosystemFile } from './lib/utils.js'
7
7
 
8
8
  export function resolve (specifier, context, nextResolve) {
9
9
  const { parentURL = null } = context
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startupjs/bundler",
3
- "version": "0.60.0-canary.1",
3
+ "version": "0.60.0-canary.17",
4
4
  "description": "Opinionated scripts and configs to develop a react-native-web project",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -17,21 +17,21 @@
17
17
  "dependencies": {
18
18
  "@babel/core": "^7.9.0",
19
19
  "@babel/plugin-syntax-jsx": "^7.0.0",
20
- "@mdx-js/mdx": "^2.3.0",
21
- "@startupjs/babel-plugin-eliminator": "^0.60.0-canary.0",
22
- "@startupjs/babel-plugin-startupjs-plugins": "^0.60.0-canary.1",
23
- "@startupjs/server": "^0.60.0-canary.0",
20
+ "@mdx-js/mdx": "^3.0.0",
21
+ "@startupjs/babel-plugin-eliminator": "^0.60.0-canary.7",
22
+ "@startupjs/babel-plugin-startupjs-plugins": "^0.60.0-canary.7",
23
+ "@startupjs/server": "^0.60.0-canary.7",
24
24
  "@svgr/core": "^8.1.0",
25
25
  "@svgr/plugin-jsx": "^8.1.0",
26
26
  "@svgr/plugin-svgo": "^8.1.0",
27
- "babel-preset-startupjs": "^0.60.0-canary.0",
27
+ "babel-preset-startupjs": "^0.60.0-canary.17",
28
28
  "connect": "^3.7.0",
29
29
  "lodash": "^4.17.20",
30
- "remark-gfm": "^1.0.0"
30
+ "remark-gfm": "4.0.1"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "cssxjs": "*",
34
34
  "react-native-svg": "*"
35
35
  },
36
- "gitHead": "302e7e8004b435ddf4310611d3b59247e4e3b89e"
36
+ "gitHead": "e4a20c7cab8953592198ab0f5157778b7bd06e35"
37
37
  }
@@ -1,23 +0,0 @@
1
- const DEFAULT_MDX_RENDERER = `
2
- import { mdx } from '@mdx-js/react'
3
- `
4
- const remarkGfm = require('remark-gfm')
5
-
6
- module.exports = async function getMDXLoader () {
7
- const mdx = await import('@mdx-js/mdx')
8
-
9
- return (source) => {
10
- source = mdx.compileSync(source, {
11
- providerImportSource: '@startupjs/mdx/client/MDXProvider/index.js',
12
- remarkPlugins: [remarkGfm]
13
- })
14
- source = DEFAULT_MDX_RENDERER + '\n' + source
15
- // To make mdx works, we should remove somehow the \n character child
16
- // from the children of MDXContent in the output source.
17
- // MDX v2 has made some changes in how it handles newlines and whitespace
18
- // compared to MDX v1. In MDX v1 newline are not inclided in the output,
19
- // but in MDX v2 it included.
20
- // console.log(source)
21
- return source
22
- }
23
- }
@@ -1,128 +0,0 @@
1
- const OBSERVER_REGEX = /(^|\W)observer\(/
2
- const OBSERVER_REPLACE = 'observer.__wrapObserverMeta(observer.__makeObserver('
3
- const OPTIONS_ANCHORS = ['forwardRef:', 'suspenseProps:']
4
-
5
- // INFO:
6
- //
7
- // The problem seems to be with observer() creating an additional
8
- // wrapper react component to host Suspense and ContextMeta.
9
- // While it also makes the target Component observable at the
10
- // same time.
11
- //
12
- // Creation of an additional wrapper component with only one
13
- // function observer() seems to confuse Fast Refresh and it loses state
14
- // of such components.
15
- //
16
- // The temporary solution for this (until it is fixed in react-native)
17
- // is to separate observer() into 2 functions:
18
- // 1. observer.__wrapObserverMeta() -- wraps component into an
19
- // additional component with Suspense and ContextMeta
20
- // 2. observer.__makeObserver() -- modifies component to become
21
- // observable
22
- //
23
- // So the following transformation transforms code the following way:
24
- // observer(App)
25
- // V V V
26
- // observer.__wrapObserverMeta(observer.__makeObserver(App))
27
- //
28
- // It's important to make this transformation as a separate step before
29
- // the usual babel transformation fires. Otherwise, if you put it
30
- // into a generic babel.config.js list of plugins, Fast Refresh
31
- // will still not properly work.
32
- //
33
- // It makes sense to only do this in development
34
-
35
- module.exports = function replaceObserverLoader (source) {
36
- const match = source.match(OBSERVER_REGEX)
37
- if (!match) return source
38
- const matchIndex = match.index
39
- const matchStr = match[0]
40
- const matchLength = matchStr.length
41
- let openBr = 1 // Count opened brackets, we start from one already opened
42
- let lastCloseCurlyBrIndex
43
- let lastOpenCurlyBrIndex
44
-
45
- // TODO: Improve figuring out that we are actually in a comment.
46
- // It will bug out when someone is specifying 'http://'
47
- // and other places inside strings.
48
-
49
- // // Track when we are inside a comment
50
- // let inBlockComment = false
51
- // let inLineComment = false
52
-
53
- for (let i = matchIndex + matchLength; i < source.length; i++) {
54
- const char = source.charAt(i)
55
-
56
- // TODO: Improve comments. See comment above for details.
57
-
58
- // // Handle comments (ignore any chars inside them)
59
-
60
- // const prevChar = (i > 0 ? source.charAt(i - 1) : '')
61
- // const lastTwoChars = `${prevChar}${char}`
62
-
63
- // // - exit comment
64
-
65
- // if (inBlockComment) {
66
- // if (lastTwoChars === '*/') inBlockComment = false
67
- // continue
68
- // }
69
-
70
- // if (inLineComment) {
71
- // if (char === '\n') inLineComment = false
72
- // continue
73
- // }
74
-
75
- // // - enter comment
76
-
77
- // if (lastTwoChars === '/*') {
78
- // inBlockComment = true
79
- // continue
80
- // }
81
-
82
- // if (lastTwoChars === '//') {
83
- // inLineComment = true
84
- // continue
85
- // }
86
-
87
- // Brackets counting logic
88
-
89
- switch (char) {
90
- case ')':
91
- --openBr
92
- break
93
- case '(':
94
- ++openBr
95
- break
96
- case '{':
97
- lastOpenCurlyBrIndex = i
98
- break
99
- case '}':
100
- lastCloseCurlyBrIndex = i
101
- break
102
- }
103
-
104
- if (openBr <= 0) {
105
- let options = ''
106
-
107
- if (lastOpenCurlyBrIndex && lastCloseCurlyBrIndex) {
108
- const sourceBetweenCurlyBrackets =
109
- source.slice(lastOpenCurlyBrIndex, lastCloseCurlyBrIndex + 1)
110
-
111
- for (const anchor of OPTIONS_ANCHORS) {
112
- if (sourceBetweenCurlyBrackets.includes(anchor)) {
113
- options = sourceBetweenCurlyBrackets
114
- break
115
- }
116
- }
117
- }
118
-
119
- if (options) options = ', ' + options
120
-
121
- source = source.slice(0, i) + ')' + options + source.slice(i)
122
- break
123
- }
124
- }
125
-
126
- source = source.replace(OBSERVER_REGEX, '$1' + OBSERVER_REPLACE)
127
- return replaceObserverLoader(source)
128
- }
package/lib/utils.js DELETED
@@ -1,12 +0,0 @@
1
- // NOTE: startupjs.config.cjs is used by the old bundler. This regex does not include it.
2
- exports.CONFIG_FILENAME_REGEX = /(?:^|[\\/])startupjs\.config\.m?[jt]sx?$/
3
- exports.PLUGIN_FILENAME_REGEX = /(?:^|[.\\/])plugin\.[mc]?[jt]sx?$/
4
- exports.LOAD_CONFIG_FILENAME_REGEX = /(?:^|[\\/])loadStartupjsConfig\.m?[jt]sx?$/
5
-
6
- exports.isStartupjsPluginEcosystemFile = filename => {
7
- return (
8
- exports.PLUGIN_FILENAME_REGEX.test(filename) ||
9
- exports.CONFIG_FILENAME_REGEX.test(filename) ||
10
- exports.LOAD_CONFIG_FILENAME_REGEX.test(filename)
11
- )
12
- }