vite 2.6.0-beta.0 → 2.6.0-beta.4

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.

Potentially problematic release.


This version of vite might be problematic. Click here for more details.

Files changed (110) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE.md +161 -3011
  3. package/bin/vite.js +2 -1
  4. package/dist/node/chunks/{dep-91aa74e8.js → dep-1e0a75a8.js} +58 -32
  5. package/dist/node/chunks/dep-1e0a75a8.js.map +1 -0
  6. package/dist/node/chunks/{dep-e36486f6.js → dep-ac1b4bf9.js} +1 -1
  7. package/dist/node/chunks/dep-ac1b4bf9.js.map +1 -0
  8. package/dist/node/chunks/{dep-c7e510f9.js → dep-ba6b30a0.js} +27538 -4953
  9. package/dist/node/chunks/dep-ba6b30a0.js.map +1 -0
  10. package/dist/node/chunks/{dep-11213a75.js → dep-c4cf6e92.js} +19 -6
  11. package/dist/node/chunks/dep-c4cf6e92.js.map +1 -0
  12. package/dist/node/chunks/{dep-eb6ef720.js → dep-d574094c.js} +18 -5
  13. package/dist/node/chunks/dep-d574094c.js.map +1 -0
  14. package/dist/node/chunks/{dep-0d2f9464.js → dep-e39b05d6.js} +18 -5
  15. package/dist/node/chunks/dep-e39b05d6.js.map +1 -0
  16. package/dist/node/cli.js +60 -23992
  17. package/dist/node/cli.js.map +1 -1
  18. package/dist/node/index.d.ts +26 -8
  19. package/dist/node/index.js +18 -15
  20. package/dist/node/index.js.map +1 -1
  21. package/dist/node/terser.js +102 -55
  22. package/package.json +28 -13
  23. package/types/package.json +3 -0
  24. package/api-extractor.json +0 -54
  25. package/dist/node/chunks/dep-0d2f9464.js.map +0 -1
  26. package/dist/node/chunks/dep-11213a75.js.map +0 -1
  27. package/dist/node/chunks/dep-91aa74e8.js.map +0 -1
  28. package/dist/node/chunks/dep-c7e510f9.js.map +0 -1
  29. package/dist/node/chunks/dep-e36486f6.js.map +0 -1
  30. package/dist/node/chunks/dep-eb6ef720.js.map +0 -1
  31. package/dist/node/terser.js.map +0 -1
  32. package/rollup.config.js +0 -389
  33. package/scripts/patchTypes.js +0 -70
  34. package/src/node/__tests__/asset.spec.ts +0 -156
  35. package/src/node/__tests__/build.spec.ts +0 -67
  36. package/src/node/__tests__/config.spec.ts +0 -166
  37. package/src/node/__tests__/packages/name/package.json +0 -3
  38. package/src/node/__tests__/packages/noname/package.json +0 -1
  39. package/src/node/__tests__/plugins/css.spec.ts +0 -116
  40. package/src/node/__tests__/scan.spec.ts +0 -118
  41. package/src/node/__tests__/utils.spec.ts +0 -40
  42. package/src/node/build.ts +0 -783
  43. package/src/node/cli.ts +0 -239
  44. package/src/node/config.ts +0 -1033
  45. package/src/node/constants.ts +0 -87
  46. package/src/node/importGlob.ts +0 -173
  47. package/src/node/index.ts +0 -88
  48. package/src/node/logger.ts +0 -167
  49. package/src/node/optimizer/esbuildDepPlugin.ts +0 -216
  50. package/src/node/optimizer/index.ts +0 -410
  51. package/src/node/optimizer/registerMissing.ts +0 -102
  52. package/src/node/optimizer/scan.ts +0 -457
  53. package/src/node/plugin.ts +0 -138
  54. package/src/node/plugins/asset.ts +0 -365
  55. package/src/node/plugins/assetImportMetaUrl.ts +0 -99
  56. package/src/node/plugins/clientInjections.ts +0 -72
  57. package/src/node/plugins/css.ts +0 -1279
  58. package/src/node/plugins/dataUri.ts +0 -64
  59. package/src/node/plugins/define.ts +0 -107
  60. package/src/node/plugins/esbuild.ts +0 -280
  61. package/src/node/plugins/html.ts +0 -673
  62. package/src/node/plugins/importAnalysis.ts +0 -614
  63. package/src/node/plugins/importAnalysisBuild.ts +0 -334
  64. package/src/node/plugins/index.ts +0 -69
  65. package/src/node/plugins/json.ts +0 -75
  66. package/src/node/plugins/loadFallback.ts +0 -19
  67. package/src/node/plugins/manifest.ts +0 -123
  68. package/src/node/plugins/modulePreloadPolyfill.ts +0 -100
  69. package/src/node/plugins/preAlias.ts +0 -22
  70. package/src/node/plugins/reporter.ts +0 -244
  71. package/src/node/plugins/resolve.ts +0 -925
  72. package/src/node/plugins/terser.ts +0 -40
  73. package/src/node/plugins/wasm.ts +0 -72
  74. package/src/node/plugins/worker.ts +0 -117
  75. package/src/node/preview.ts +0 -82
  76. package/src/node/server/__tests__/fixtures/none/nested/package.json +0 -3
  77. package/src/node/server/__tests__/fixtures/pnpm/nested/package.json +0 -3
  78. package/src/node/server/__tests__/fixtures/pnpm/package.json +0 -3
  79. package/src/node/server/__tests__/fixtures/pnpm/pnpm-workspace.yaml +0 -0
  80. package/src/node/server/__tests__/fixtures/yarn/nested/package.json +0 -3
  81. package/src/node/server/__tests__/fixtures/yarn/package.json +0 -6
  82. package/src/node/server/__tests__/search-root.spec.ts +0 -31
  83. package/src/node/server/hmr.ts +0 -489
  84. package/src/node/server/http.ts +0 -198
  85. package/src/node/server/index.ts +0 -705
  86. package/src/node/server/middlewares/base.ts +0 -52
  87. package/src/node/server/middlewares/error.ts +0 -98
  88. package/src/node/server/middlewares/indexHtml.ts +0 -170
  89. package/src/node/server/middlewares/proxy.ts +0 -124
  90. package/src/node/server/middlewares/spaFallback.ts +0 -32
  91. package/src/node/server/middlewares/static.ts +0 -153
  92. package/src/node/server/middlewares/time.ts +0 -18
  93. package/src/node/server/middlewares/transform.ts +0 -196
  94. package/src/node/server/moduleGraph.ts +0 -200
  95. package/src/node/server/openBrowser.ts +0 -101
  96. package/src/node/server/pluginContainer.ts +0 -546
  97. package/src/node/server/searchRoot.ts +0 -70
  98. package/src/node/server/send.ts +0 -54
  99. package/src/node/server/sourcemap.ts +0 -54
  100. package/src/node/server/transformRequest.ts +0 -168
  101. package/src/node/server/ws.ts +0 -131
  102. package/src/node/ssr/__tests__/ssrTransform.spec.ts +0 -309
  103. package/src/node/ssr/ssrExternal.ts +0 -161
  104. package/src/node/ssr/ssrManifestPlugin.ts +0 -53
  105. package/src/node/ssr/ssrModuleLoader.ts +0 -214
  106. package/src/node/ssr/ssrStacktrace.ts +0 -75
  107. package/src/node/ssr/ssrTransform.ts +0 -452
  108. package/src/node/tsconfig.json +0 -14
  109. package/src/node/utils.ts +0 -565
  110. package/tsconfig.base.json +0 -11
@@ -1,196 +0,0 @@
1
- import path from 'path'
2
- import { ViteDevServer } from '..'
3
- import { Connect } from 'types/connect'
4
- import {
5
- cleanUrl,
6
- createDebugger,
7
- injectQuery,
8
- isImportRequest,
9
- isJSRequest,
10
- normalizePath,
11
- prettifyUrl,
12
- removeImportQuery,
13
- removeTimestampQuery,
14
- unwrapId
15
- } from '../../utils'
16
- import { send } from '../send'
17
- import { transformRequest } from '../transformRequest'
18
- import { isHTMLProxy } from '../../plugins/html'
19
- import chalk from 'chalk'
20
- import {
21
- CLIENT_PUBLIC_PATH,
22
- DEP_VERSION_RE,
23
- NULL_BYTE_PLACEHOLDER
24
- } from '../../constants'
25
- import {
26
- isCSSRequest,
27
- isDirectCSSRequest,
28
- isDirectRequest
29
- } from '../../plugins/css'
30
-
31
- /**
32
- * Time (ms) Vite has to full-reload the page before returning
33
- * an empty response.
34
- */
35
- const NEW_DEPENDENCY_BUILD_TIMEOUT = 1000
36
-
37
- const debugCache = createDebugger('vite:cache')
38
- const isDebug = !!process.env.DEBUG
39
-
40
- const knownIgnoreList = new Set(['/', '/favicon.ico'])
41
-
42
- export function transformMiddleware(
43
- server: ViteDevServer
44
- ): Connect.NextHandleFunction {
45
- const {
46
- config: { root, logger, cacheDir },
47
- moduleGraph
48
- } = server
49
-
50
- // determine the url prefix of files inside cache directory
51
- let cacheDirPrefix: string | undefined
52
- if (cacheDir) {
53
- const cacheDirRelative = normalizePath(path.relative(root, cacheDir))
54
- if (cacheDirRelative.startsWith('../')) {
55
- // if the cache directory is outside root, the url prefix would be something
56
- // like '/@fs/absolute/path/to/node_modules/.vite'
57
- cacheDirPrefix = `/@fs/${normalizePath(cacheDir).replace(/^\//, '')}`
58
- } else {
59
- // if the cache directory is inside root, the url prefix would be something
60
- // like '/node_modules/.vite'
61
- cacheDirPrefix = `/${cacheDirRelative}`
62
- }
63
- }
64
-
65
- // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
66
- return async function viteTransformMiddleware(req, res, next) {
67
- if (req.method !== 'GET' || knownIgnoreList.has(req.url!)) {
68
- return next()
69
- }
70
-
71
- if (
72
- server._pendingReload &&
73
- // always allow vite client requests so that it can trigger page reload
74
- !req.url?.startsWith(CLIENT_PUBLIC_PATH) &&
75
- !req.url?.includes('vite/dist/client')
76
- ) {
77
- // missing dep pending reload, hold request until reload happens
78
- server._pendingReload.then(() =>
79
- // If the refresh has not happened after timeout, Vite considers
80
- // something unexpected has happened. In this case, Vite
81
- // returns an empty response that will error.
82
- setTimeout(() => {
83
- // Don't do anything if response has already been sent
84
- if (res.writableEnded) return
85
- // status code request timeout
86
- res.statusCode = 408
87
- res.end(
88
- `<h1>[vite] Something unexpected happened while optimizing "${req.url}"<h1>` +
89
- `<p>The current page should have reloaded by now</p>`
90
- )
91
- }, NEW_DEPENDENCY_BUILD_TIMEOUT)
92
- )
93
- return
94
- }
95
-
96
- let url = decodeURI(removeTimestampQuery(req.url!)).replace(
97
- NULL_BYTE_PLACEHOLDER,
98
- '\0'
99
- )
100
-
101
- const withoutQuery = cleanUrl(url)
102
-
103
- try {
104
- const isSourceMap = withoutQuery.endsWith('.map')
105
- // since we generate source map references, handle those requests here
106
- if (isSourceMap) {
107
- const originalUrl = url.replace(/\.map($|\?)/, '$1')
108
- const map = (await moduleGraph.getModuleByUrl(originalUrl))
109
- ?.transformResult?.map
110
- if (map) {
111
- return send(req, res, JSON.stringify(map), 'json')
112
- } else {
113
- return next()
114
- }
115
- }
116
-
117
- // check if public dir is inside root dir
118
- const publicDir = normalizePath(server.config.publicDir)
119
- const rootDir = normalizePath(server.config.root)
120
- if (publicDir.startsWith(rootDir)) {
121
- const publicPath = `${publicDir.slice(rootDir.length)}/`
122
- // warn explicit public paths
123
- if (url.startsWith(publicPath)) {
124
- logger.warn(
125
- chalk.yellow(
126
- `files in the public directory are served at the root path.\n` +
127
- `Instead of ${chalk.cyan(url)}, use ${chalk.cyan(
128
- url.replace(publicPath, '/')
129
- )}.`
130
- )
131
- )
132
- }
133
- }
134
-
135
- if (
136
- isJSRequest(url) ||
137
- isImportRequest(url) ||
138
- isCSSRequest(url) ||
139
- isHTMLProxy(url)
140
- ) {
141
- // strip ?import
142
- url = removeImportQuery(url)
143
- // Strip valid id prefix. This is prepended to resolved Ids that are
144
- // not valid browser import specifiers by the importAnalysis plugin.
145
- url = unwrapId(url)
146
-
147
- // for CSS, we need to differentiate between normal CSS requests and
148
- // imports
149
- if (
150
- isCSSRequest(url) &&
151
- !isDirectRequest(url) &&
152
- req.headers.accept?.includes('text/css')
153
- ) {
154
- url = injectQuery(url, 'direct')
155
- }
156
-
157
- // check if we can return 304 early
158
- const ifNoneMatch = req.headers['if-none-match']
159
- if (
160
- ifNoneMatch &&
161
- (await moduleGraph.getModuleByUrl(url))?.transformResult?.etag ===
162
- ifNoneMatch
163
- ) {
164
- isDebug && debugCache(`[304] ${prettifyUrl(url, root)}`)
165
- res.statusCode = 304
166
- return res.end()
167
- }
168
-
169
- // resolve, load and transform using the plugin container
170
- const result = await transformRequest(url, server, {
171
- html: req.headers.accept?.includes('text/html')
172
- })
173
- if (result) {
174
- const type = isDirectCSSRequest(url) ? 'css' : 'js'
175
- const isDep =
176
- DEP_VERSION_RE.test(url) ||
177
- (cacheDirPrefix && url.startsWith(cacheDirPrefix))
178
- return send(
179
- req,
180
- res,
181
- result.code,
182
- type,
183
- result.etag,
184
- // allow browser to cache npm deps!
185
- isDep ? 'max-age=31536000,immutable' : 'no-cache',
186
- result.map
187
- )
188
- }
189
- }
190
- } catch (e) {
191
- return next(e)
192
- }
193
-
194
- next()
195
- }
196
- }
@@ -1,200 +0,0 @@
1
- import { extname } from 'path'
2
- import { isDirectCSSRequest } from '../plugins/css'
3
- import {
4
- cleanUrl,
5
- normalizePath,
6
- removeImportQuery,
7
- removeTimestampQuery
8
- } from '../utils'
9
- import { FS_PREFIX } from '../constants'
10
- import { TransformResult } from './transformRequest'
11
- import { PluginContainer } from './pluginContainer'
12
- import { parse as parseUrl } from 'url'
13
-
14
- export class ModuleNode {
15
- /**
16
- * Public served url path, starts with /
17
- */
18
- url: string
19
- /**
20
- * Resolved file system path + query
21
- */
22
- id: string | null = null
23
- file: string | null = null
24
- type: 'js' | 'css'
25
- importers = new Set<ModuleNode>()
26
- importedModules = new Set<ModuleNode>()
27
- acceptedHmrDeps = new Set<ModuleNode>()
28
- isSelfAccepting = false
29
- transformResult: TransformResult | null = null
30
- ssrTransformResult: TransformResult | null = null
31
- ssrModule: Record<string, any> | null = null
32
- lastHMRTimestamp = 0
33
-
34
- constructor(url: string) {
35
- this.url = url
36
- this.type = isDirectCSSRequest(url) ? 'css' : 'js'
37
- }
38
- }
39
-
40
- function invalidateSSRModule(mod: ModuleNode, seen: Set<ModuleNode>) {
41
- if (seen.has(mod)) {
42
- return
43
- }
44
- seen.add(mod)
45
- mod.ssrModule = null
46
- mod.importers.forEach((importer) => invalidateSSRModule(importer, seen))
47
- }
48
- export class ModuleGraph {
49
- urlToModuleMap = new Map<string, ModuleNode>()
50
- idToModuleMap = new Map<string, ModuleNode>()
51
- // a single file may corresponds to multiple modules with different queries
52
- fileToModulesMap = new Map<string, Set<ModuleNode>>()
53
- safeModulesPath = new Set<string>()
54
- container: PluginContainer
55
-
56
- constructor(container: PluginContainer) {
57
- this.container = container
58
- }
59
-
60
- async getModuleByUrl(rawUrl: string): Promise<ModuleNode | undefined> {
61
- const [url] = await this.resolveUrl(rawUrl)
62
- return this.urlToModuleMap.get(url)
63
- }
64
-
65
- getModuleById(id: string): ModuleNode | undefined {
66
- return this.idToModuleMap.get(removeTimestampQuery(id))
67
- }
68
-
69
- getModulesByFile(file: string): Set<ModuleNode> | undefined {
70
- return this.fileToModulesMap.get(file)
71
- }
72
-
73
- onFileChange(file: string): void {
74
- const mods = this.getModulesByFile(file)
75
- if (mods) {
76
- const seen = new Set<ModuleNode>()
77
- mods.forEach((mod) => {
78
- this.invalidateModule(mod, seen)
79
- })
80
- }
81
- }
82
-
83
- invalidateModule(mod: ModuleNode, seen: Set<ModuleNode> = new Set()): void {
84
- mod.transformResult = null
85
- mod.ssrTransformResult = null
86
- invalidateSSRModule(mod, seen)
87
- }
88
-
89
- invalidateAll(): void {
90
- const seen = new Set<ModuleNode>()
91
- this.idToModuleMap.forEach((mod) => {
92
- this.invalidateModule(mod, seen)
93
- })
94
- }
95
-
96
- /**
97
- * Update the module graph based on a module's updated imports information
98
- * If there are dependencies that no longer have any importers, they are
99
- * returned as a Set.
100
- */
101
- async updateModuleInfo(
102
- mod: ModuleNode,
103
- importedModules: Set<string | ModuleNode>,
104
- acceptedModules: Set<string | ModuleNode>,
105
- isSelfAccepting: boolean
106
- ): Promise<Set<ModuleNode> | undefined> {
107
- mod.isSelfAccepting = isSelfAccepting
108
- const prevImports = mod.importedModules
109
- const nextImports = (mod.importedModules = new Set())
110
- let noLongerImported: Set<ModuleNode> | undefined
111
- // update import graph
112
- for (const imported of importedModules) {
113
- const dep =
114
- typeof imported === 'string'
115
- ? await this.ensureEntryFromUrl(imported)
116
- : imported
117
- dep.importers.add(mod)
118
- nextImports.add(dep)
119
- }
120
- // remove the importer from deps that were imported but no longer are.
121
- prevImports.forEach((dep) => {
122
- if (!nextImports.has(dep)) {
123
- dep.importers.delete(mod)
124
- if (!dep.importers.size) {
125
- // dependency no longer imported
126
- ;(noLongerImported || (noLongerImported = new Set())).add(dep)
127
- }
128
- }
129
- })
130
- // update accepted hmr deps
131
- const deps = (mod.acceptedHmrDeps = new Set())
132
- for (const accepted of acceptedModules) {
133
- const dep =
134
- typeof accepted === 'string'
135
- ? await this.ensureEntryFromUrl(accepted)
136
- : accepted
137
- deps.add(dep)
138
- }
139
- return noLongerImported
140
- }
141
-
142
- async ensureEntryFromUrl(rawUrl: string): Promise<ModuleNode> {
143
- const [url, resolvedId] = await this.resolveUrl(rawUrl)
144
- let mod = this.urlToModuleMap.get(url)
145
- if (!mod) {
146
- mod = new ModuleNode(url)
147
- this.urlToModuleMap.set(url, mod)
148
- mod.id = resolvedId
149
- this.idToModuleMap.set(resolvedId, mod)
150
- const file = (mod.file = cleanUrl(resolvedId))
151
- let fileMappedModules = this.fileToModulesMap.get(file)
152
- if (!fileMappedModules) {
153
- fileMappedModules = new Set()
154
- this.fileToModulesMap.set(file, fileMappedModules)
155
- }
156
- fileMappedModules.add(mod)
157
- }
158
- return mod
159
- }
160
-
161
- // some deps, like a css file referenced via @import, don't have its own
162
- // url because they are inlined into the main css import. But they still
163
- // need to be represented in the module graph so that they can trigger
164
- // hmr in the importing css file.
165
- createFileOnlyEntry(file: string): ModuleNode {
166
- file = normalizePath(file)
167
- let fileMappedModules = this.fileToModulesMap.get(file)
168
- if (!fileMappedModules) {
169
- fileMappedModules = new Set()
170
- this.fileToModulesMap.set(file, fileMappedModules)
171
- }
172
-
173
- const url = `${FS_PREFIX}${file}`
174
- for (const m of fileMappedModules) {
175
- if (m.url === url || m.id === file) {
176
- return m
177
- }
178
- }
179
-
180
- const mod = new ModuleNode(url)
181
- mod.file = file
182
- fileMappedModules.add(mod)
183
- return mod
184
- }
185
-
186
- // for incoming urls, it is important to:
187
- // 1. remove the HMR timestamp query (?t=xxxx)
188
- // 2. resolve its extension so that urls with or without extension all map to
189
- // the same module
190
- async resolveUrl(url: string): Promise<[string, string]> {
191
- url = removeImportQuery(removeTimestampQuery(url))
192
- const resolvedId = (await this.container.resolveId(url))?.id || url
193
- const ext = extname(cleanUrl(resolvedId))
194
- const { pathname, search, hash } = parseUrl(url)
195
- if (ext && !pathname!.endsWith(ext)) {
196
- url = pathname + ext + (search || '') + (hash || '')
197
- }
198
- return [url, resolvedId]
199
- }
200
- }
@@ -1,101 +0,0 @@
1
- /**
2
- * The following is modified based on source found in
3
- * https://github.com/facebook/create-react-app
4
- *
5
- * MIT Licensed
6
- * Copyright (c) 2015-present, Facebook, Inc.
7
- * https://github.com/facebook/create-react-app/blob/master/LICENSE
8
- *
9
- */
10
-
11
- import path from 'path'
12
- import open from 'open'
13
- import execa from 'execa'
14
- import chalk from 'chalk'
15
- import { execSync } from 'child_process'
16
- import { Logger } from '../logger'
17
-
18
- // https://github.com/sindresorhus/open#app
19
- const OSX_CHROME = 'google chrome'
20
-
21
- /**
22
- * Reads the BROWSER environment variable and decides what to do with it.
23
- * Returns true if it opened a browser or ran a node.js script, otherwise false.
24
- */
25
- export function openBrowser(
26
- url: string,
27
- opt: string | true,
28
- logger: Logger
29
- ): boolean {
30
- // The browser executable to open.
31
- // See https://github.com/sindresorhus/open#app for documentation.
32
- const browser = typeof opt === 'string' ? opt : process.env.BROWSER || ''
33
- if (browser.toLowerCase().endsWith('.js')) {
34
- return executeNodeScript(browser, url, logger)
35
- } else if (browser.toLowerCase() !== 'none') {
36
- return startBrowserProcess(browser, url)
37
- }
38
- return false
39
- }
40
-
41
- function executeNodeScript(scriptPath: string, url: string, logger: Logger) {
42
- const extraArgs = process.argv.slice(2)
43
- const child = execa('node', [scriptPath, ...extraArgs, url], {
44
- stdio: 'inherit'
45
- })
46
- child.on('close', (code) => {
47
- if (code !== 0) {
48
- logger.error(
49
- chalk.red(
50
- `\nThe script specified as BROWSER environment variable failed.\n\n${chalk.cyan(
51
- scriptPath
52
- )} exited with code ${code}.`
53
- ),
54
- { error: null }
55
- )
56
- }
57
- })
58
- return true
59
- }
60
-
61
- function startBrowserProcess(browser: string | undefined, url: string) {
62
- // If we're on OS X, the user hasn't specifically
63
- // requested a different browser, we can try opening
64
- // Chrome with AppleScript. This lets us reuse an
65
- // existing tab when possible instead of creating a new one.
66
- const shouldTryOpenChromeWithAppleScript =
67
- process.platform === 'darwin' && (browser === '' || browser === OSX_CHROME)
68
-
69
- if (shouldTryOpenChromeWithAppleScript) {
70
- try {
71
- // Try our best to reuse existing tab
72
- // on OS X Google Chrome with AppleScript
73
- execSync('ps cax | grep "Google Chrome"')
74
- execSync('osascript openChrome.applescript "' + encodeURI(url) + '"', {
75
- cwd: path.dirname(require.resolve('vite/bin/openChrome.applescript')),
76
- stdio: 'ignore'
77
- })
78
- return true
79
- } catch (err) {
80
- // Ignore errors
81
- }
82
- }
83
-
84
- // Another special case: on OS X, check if BROWSER has been set to "open".
85
- // In this case, instead of passing the string `open` to `open` function (which won't work),
86
- // just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
87
- // https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768
88
- if (process.platform === 'darwin' && browser === 'open') {
89
- browser = undefined
90
- }
91
-
92
- // Fallback to open
93
- // (It will always open new tab)
94
- try {
95
- const options: open.Options = browser ? { app: { name: browser } } : {}
96
- open(url, options).catch(() => {}) // Prevent `unhandledRejection` error.
97
- return true
98
- } catch (err) {
99
- return false
100
- }
101
- }