提交 9b6ea9d4 编写于 作者: J Joe Haddad 提交者: JJ Kasper

Refactor Webpack Configuration (#9651)

* WIP

* Move data experiment

* Do not throw away rules

* Remove test code

* Correct next data behavior

* Add support for async composing

* Remove unnecessary workaround

* Rename Field
上级 d64587e1
import chalk from 'chalk'
import crypto from 'crypto'
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
......@@ -6,7 +5,6 @@ import path from 'path'
// @ts-ignore: Currently missing types
import PnpWebpackPlugin from 'pnp-webpack-plugin'
import webpack from 'webpack'
import {
DOT_NEXT_ALIAS,
NEXT_PROJECT_ROOT,
......@@ -14,15 +12,14 @@ import {
PAGES_DIR_ALIAS,
} from '../lib/constants'
import { fileExists } from '../lib/file-exists'
import { findConfig } from '../lib/find-config'
import { resolveRequest } from '../lib/resolve-request'
import {
CLIENT_STATIC_FILES_RUNTIME_MAIN,
CLIENT_STATIC_FILES_RUNTIME_POLYFILLS,
CLIENT_STATIC_FILES_RUNTIME_WEBPACK,
REACT_LOADABLE_MANIFEST,
SERVER_DIRECTORY,
SERVERLESS_DIRECTORY,
SERVER_DIRECTORY,
} from '../next-server/lib/constants'
import { findPageFile } from '../server/lib/find-page-file'
import { WebpackEntrypoints } from './entries'
......@@ -31,6 +28,7 @@ import {
PluginMetaData,
VALID_MIDDLEWARE,
} from './plugins/collect-plugins'
import { build as buildConfiguration } from './webpack/config'
// @ts-ignore: JS file
import { pluginLoaderOptions } from './webpack/loaders/next-plugin-loader'
import BuildManifestPlugin from './webpack/plugins/build-manifest-plugin'
......@@ -93,105 +91,6 @@ function getOptimizedAliases(isServer: boolean): { [pkg: string]: string } {
}
}
async function getPostCssPlugins(dir: string): Promise<unknown[]> {
function load(plugins: { [key: string]: object | false }): unknown[] {
return Object.keys(plugins)
.map(pkg => {
const options = plugins[pkg]
if (options === false) {
return false
}
const pluginPath = resolveRequest(pkg, `${dir}/`)
if (options == null || Object.keys(options).length === 0) {
return require(pluginPath)
}
return require(pluginPath)(options)
})
.filter(Boolean)
}
const config = await findConfig<{ plugins: { [key: string]: object } }>(
dir,
'postcss'
)
let target: unknown[]
if (!config) {
target = load({
[require.resolve('postcss-flexbugs-fixes')]: {},
[require.resolve('postcss-preset-env')]: {
autoprefixer: {
// Disable legacy flexbox support
flexbox: 'no-2009',
},
// Enable CSS features that have shipped to the
// web platform, i.e. in 2+ browsers unflagged.
stage: 3,
},
})
} else {
const plugins = config.plugins
if (plugins == null || typeof plugins !== 'object') {
throw new Error(
`Your custom PostCSS configuration must export a \`plugins\` key.`
)
}
const invalidKey = Object.keys(config).find(key => key !== 'plugins')
if (invalidKey) {
console.warn(
`${chalk.yellow.bold(
'Warning'
)}: Your PostCSS configuration defines a field which is not supported (\`${invalidKey}\`). ` +
`Please remove this configuration value.`
)
}
// These plugins cannot be enabled by the user because they'll conflict with
// `css-loader`'s behavior to make us compatible with webpack.
;[
'postcss-modules-values',
'postcss-modules-scope',
'postcss-modules-extract-imports',
'postcss-modules-local-by-default',
].forEach(plugin => {
if (!plugins.hasOwnProperty(plugin)) {
return
}
console.warn(
`${chalk.yellow.bold('Warning')}: Please remove the ${chalk.underline(
plugin
)} plugin from your PostCSS configuration. ` +
`This plugin is automatically configured by Next.js.`
)
delete plugins[plugin]
})
// Next.js doesn't support CSS Modules yet. When we do, we should respect the
// options passed to this plugin (even though we need to remove the plugin
// itself).
if (plugins['postcss-modules']) {
delete plugins['postcss-modules']
console.warn(
`${chalk.yellow.bold(
'Warning'
)}: Next.js does not support CSS Modules (yet). The ${chalk.underline(
'postcss-modules'
)} plugin will have no effect.`
)
}
target = load(plugins as { [key: string]: object })
}
return target
}
export default async function getBaseWebpackConfig(
dir: string,
{
......@@ -504,15 +403,7 @@ export default async function getBaseWebpackConfig(
customAppFile = path.resolve(path.join(pagesDir, customAppFile))
}
const postCssPlugins: unknown[] = config.experimental.css
? await getPostCssPlugins(dir)
: []
let webpackConfig: webpack.Configuration = {
devtool,
mode: webpackMode,
name: isServer ? 'server' : 'client',
target: isServer ? 'node' : 'web',
externals: !isServer
? undefined
: !isServerless
......@@ -741,14 +632,7 @@ export default async function getBaseWebpackConfig(
},
// @ts-ignore this is filtered
module: {
strictExportPresence: true,
rules: [
config.experimental.ampBindInitData &&
!isServer && {
test: /\.(tsx|ts|js|mjs|jsx)$/,
include: [path.join(dir, 'data')],
use: 'next-data-loader',
},
{
test: /\.(tsx|ts|js|mjs|jsx)$/,
include: [dir, ...babelIncludeRegexes],
......@@ -760,132 +644,6 @@ export default async function getBaseWebpackConfig(
},
use: defaultLoaders.babel,
},
config.experimental.css &&
// Support CSS imports
({
oneOf: [
{
test: /\.css$/,
issuer: { include: [customAppFile].filter(Boolean) },
use: isServer
? // Global CSS is ignored on the server because it's only needed
// on the client-side.
require.resolve('ignore-loader')
: [
// During development we load CSS via JavaScript so we can
// hot reload it without refreshing the page.
dev && {
loader: require.resolve('style-loader'),
options: {
// By default, style-loader injects CSS into the bottom
// of <head>. This causes ordering problems between dev
// and prod. To fix this, we render a <noscript> tag as
// an anchor for the styles to be placed before. These
// styles will be applied _before_ <style jsx global>.
insert: function(element: Node) {
// These elements should always exist. If they do not,
// this code should fail.
var anchorElement = document.querySelector(
'#__next_css__DO_NOT_USE__'
)!
var parentNode = anchorElement.parentNode! // Normally <head>
// Each style tag should be placed right before our
// anchor. By inserting before and not after, we do not
// need to track the last inserted element.
parentNode.insertBefore(element, anchorElement)
// Remember: this is development only code.
//
// After styles are injected, we need to remove the
// <style> tags that set `body { display: none; }`.
//
// We use `requestAnimationFrame` as a way to defer
// this operation since there may be multiple style
// tags.
;(self.requestAnimationFrame || setTimeout)(
function() {
for (
var x = document.querySelectorAll(
'[data-next-hide-fouc]'
),
i = x.length;
i--;
) {
x[i].parentNode!.removeChild(x[i])
}
}
)
},
},
},
// When building for production we extract CSS into
// separate files.
!dev && {
loader: MiniCssExtractPlugin.loader,
options: {},
},
// Resolve CSS `@import`s and `url()`s
{
loader: require.resolve('css-loader'),
options: { importLoaders: 1, sourceMap: true },
},
// Compile CSS
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: postCssPlugins,
sourceMap: true,
},
},
].filter(Boolean),
// A global CSS import always has side effects. Webpack will tree
// shake the CSS without this option if the issuer claims to have
// no side-effects.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
{
test: /\.css$/,
use: isServer
? require.resolve('ignore-loader')
: {
loader: 'error-loader',
options: {
reason:
`Global CSS ${chalk.bold(
'cannot'
)} be imported from files other than your ${chalk.bold(
'Custom <App>'
)}. Please move all global CSS imports to ${chalk.cyan(
customAppFile
? path.relative(dir, customAppFile)
: 'pages/_app.js'
)}.\n` +
`Read more: https://err.sh/next.js/global-css`,
},
},
},
],
} as webpack.RuleSetRule),
config.experimental.css &&
({
loader: require.resolve('file-loader'),
issuer: {
// file-loader is only used for CSS files, e.g. url() for a SVG
// or font files
test: /\.css$/,
},
// Exclude extensions that webpack handles by default
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash].[ext]',
},
} as webpack.RuleSetRule),
].filter(Boolean),
},
plugins: [
......@@ -1077,6 +835,15 @@ export default async function getBaseWebpackConfig(
].filter((Boolean as any) as ExcludesFalse),
}
webpackConfig = await buildConfiguration(webpackConfig, {
rootDirectory: dir,
customAppFile,
isDevelopment: dev,
isServer,
hasSupportCss: !!config.experimental.css,
hasExperimentalData: !!config.experimental.ampBindInitData,
})
if (typeof config.webpack === 'function') {
webpackConfig = config.webpack(webpackConfig, {
dir,
......
import curry from 'lodash.curry'
import { Configuration } from 'webpack'
import { ConfigurationContext } from '../utils'
export const base = curry(function base(
ctx: ConfigurationContext,
config: Configuration
) {
config.mode = ctx.isDevelopment ? 'development' : 'production'
config.name = ctx.isServer ? 'server' : 'client'
config.target = ctx.isServer ? 'node' : 'web'
config.devtool = ctx.isDevelopment
? 'cheap-module-source-map'
: ctx.isProduction
? false
: false
if (!config.module) {
config.module = { rules: [] }
}
config.module.strictExportPresence = true
return config
})
import curry from 'lodash.curry'
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
import path from 'path'
import { Configuration } from 'webpack'
import { loader } from '../../helpers'
import { ConfigurationContext, ConfigurationFn, pipe } from '../../utils'
import { getGlobalImportError } from './messages'
import { getPostCssPlugins } from './plugins'
import webpack from 'webpack'
function getStyleLoader({
isDevelopment,
}: {
isDevelopment: boolean
}): webpack.RuleSetUseItem {
return isDevelopment
? {
loader: require.resolve('style-loader'),
options: {
// By default, style-loader injects CSS into the bottom
// of <head>. This causes ordering problems between dev
// and prod. To fix this, we render a <noscript> tag as
// an anchor for the styles to be placed before. These
// styles will be applied _before_ <style jsx global>.
insert: function(element: Node) {
// These elements should always exist. If they do not,
// this code should fail.
var anchorElement = document.querySelector(
'#__next_css__DO_NOT_USE__'
)!
var parentNode = anchorElement.parentNode! // Normally <head>
// Each style tag should be placed right before our
// anchor. By inserting before and not after, we do not
// need to track the last inserted element.
parentNode.insertBefore(element, anchorElement)
// Remember: this is development only code.
//
// After styles are injected, we need to remove the
// <style> tags that set `body { display: none; }`.
//
// We use `requestAnimationFrame` as a way to defer
// this operation since there may be multiple style
// tags.
;(self.requestAnimationFrame || setTimeout)(function() {
for (
var x = document.querySelectorAll('[data-next-hide-fouc]'),
i = x.length;
i--;
) {
x[i].parentNode!.removeChild(x[i])
}
})
},
},
}
: {
loader: MiniCssExtractPlugin.loader,
options: {},
}
}
export const css = curry(async function css(
enabled: boolean,
ctx: ConfigurationContext,
config: Configuration
) {
if (!enabled) {
return config
}
const fns: ConfigurationFn[] = []
if (ctx.isServer) {
fns.push(
loader({
oneOf: [{ test: /\.css$/, use: require.resolve('ignore-loader') }],
})
)
} else if (ctx.customAppFile) {
const postCssPlugins = await getPostCssPlugins(ctx.rootDirectory)
fns.push(
loader({
oneOf: [
{
// A global CSS import always has side effects. Webpack will tree
// shake the CSS without this option if the issuer claims to have
// no side-effects.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
test: /\.css$/,
issuer: { include: ctx.customAppFile },
use: [
// Add appropriate development more or production mode style
// loader
getStyleLoader({ isDevelopment: ctx.isDevelopment }),
// Resolve CSS `@import`s and `url()`s
{
loader: require.resolve('css-loader'),
options: { importLoaders: 1, sourceMap: true },
},
// Compile CSS
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: postCssPlugins,
sourceMap: true,
},
},
],
},
],
})
)
}
// Throw an error for Global CSS used outside of our custom <App> file
fns.push(
loader({
oneOf: [
{
test: /\.css$/,
use: {
loader: 'error-loader',
options: {
reason: getGlobalImportError(
ctx.customAppFile &&
path.relative(ctx.rootDirectory, ctx.customAppFile)
),
},
},
},
],
})
)
// Automatically transform references to files (i.e. url()) into URLs
// e.g. url(./logo.svg)
fns.push(
loader({
oneOf: [
{
// This should only be applied to CSS files
issuer: { test: /\.css$/ },
// Exclude extensions that webpack handles by default
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
use: {
// `file-loader` always emits a URL reference, where `url-loader`
// might inline the asset as a data URI
loader: require.resolve('file-loader'),
options: {
// Hash the file for immutable cacheability
name: 'static/media/[name].[hash].[ext]',
},
},
},
],
})
)
const fn = pipe(...fns)
return fn(config)
})
import chalk from 'chalk'
export function getGlobalImportError(file: string | null) {
return `Global CSS ${chalk.bold(
'cannot'
)} be imported from files other than your ${chalk.bold(
'Custom <App>'
)}. Please move all global CSS imports to ${chalk.cyan(
file ? file : 'pages/_app.js'
)}.\nRead more: https://err.sh/next.js/global-css`
}
import chalk from 'chalk'
import { findConfig } from '../../../../../lib/find-config'
import { resolveRequest } from '../../../../../lib/resolve-request'
export async function getPostCssPlugins(dir: string): Promise<unknown[]> {
function load(plugins: { [key: string]: object | false }): unknown[] {
return Object.keys(plugins)
.map(pkg => {
const options = plugins[pkg]
if (options === false) {
return false
}
const pluginPath = resolveRequest(pkg, `${dir}/`)
if (options == null || Object.keys(options).length === 0) {
return require(pluginPath)
}
return require(pluginPath)(options)
})
.filter(Boolean)
}
const config = await findConfig<{ plugins: { [key: string]: object } }>(
dir,
'postcss'
)
let target: unknown[]
if (!config) {
target = load({
[require.resolve('postcss-flexbugs-fixes')]: {},
[require.resolve('postcss-preset-env')]: {
autoprefixer: {
// Disable legacy flexbox support
flexbox: 'no-2009',
},
// Enable CSS features that have shipped to the
// web platform, i.e. in 2+ browsers unflagged.
stage: 3,
},
})
} else {
const plugins = config.plugins
if (plugins == null || typeof plugins !== 'object') {
throw new Error(
`Your custom PostCSS configuration must export a \`plugins\` key.`
)
}
const invalidKey = Object.keys(config).find(key => key !== 'plugins')
if (invalidKey) {
console.warn(
`${chalk.yellow.bold(
'Warning'
)}: Your PostCSS configuration defines a field which is not supported (\`${invalidKey}\`). ` +
`Please remove this configuration value.`
)
}
// These plugins cannot be enabled by the user because they'll conflict with
// `css-loader`'s behavior to make us compatible with webpack.
;[
'postcss-modules-values',
'postcss-modules-scope',
'postcss-modules-extract-imports',
'postcss-modules-local-by-default',
].forEach(plugin => {
if (!plugins.hasOwnProperty(plugin)) {
return
}
console.warn(
`${chalk.yellow.bold('Warning')}: Please remove the ${chalk.underline(
plugin
)} plugin from your PostCSS configuration. ` +
`This plugin is automatically configured by Next.js.`
)
delete plugins[plugin]
})
// Next.js doesn't support CSS Modules yet. When we do, we should respect the
// options passed to this plugin (even though we need to remove the plugin
// itself).
if (plugins['postcss-modules']) {
delete plugins['postcss-modules']
console.warn(
`${chalk.yellow.bold(
'Warning'
)}: Next.js does not support CSS Modules (yet). The ${chalk.underline(
'postcss-modules'
)} plugin will have no effect.`
)
}
target = load(plugins as { [key: string]: object })
}
return target
}
import curry from 'lodash.curry'
import path from 'path'
import { Configuration } from 'webpack'
import { unshiftLoader } from '../helpers'
import { ConfigurationContext, pipe } from '../utils'
export const experimentData = curry(function experimentData(
enabled: boolean,
ctx: ConfigurationContext,
config: Configuration
) {
if (!enabled) {
return config
}
if (ctx.isServer) {
return config
}
const fn = pipe(
unshiftLoader({
test: /\.(tsx|ts|js|mjs|jsx)$/,
include: [path.join(ctx.rootDirectory, 'data')],
use: 'next-data-loader',
})
)
return fn(config)
})
import curry from 'lodash.curry'
import { Configuration, RuleSetRule } from 'webpack'
export const loader = curry(function loader(
rule: RuleSetRule,
config: Configuration
) {
if (!config.module) {
config.module = { rules: [] }
}
if (rule.oneOf) {
const existing = config.module.rules.find(rule => rule.oneOf)
if (existing) {
existing.oneOf!.push(...rule.oneOf)
return config
}
}
config.module.rules.push(rule)
return config
})
export const unshiftLoader = curry(function loader(
rule: RuleSetRule,
config: Configuration
) {
if (!config.module) {
config.module = { rules: [] }
}
if (rule.oneOf) {
const existing = config.module.rules.find(rule => rule.oneOf)
if (existing) {
existing.oneOf!.unshift(...rule.oneOf)
return config
}
}
config.module.rules.unshift(rule)
return config
})
import webpack from 'webpack'
import { base } from './blocks/base'
import { css } from './blocks/css'
import { ConfigurationContext, pipe } from './utils'
import { experimentData } from './blocks/experiment-data'
export async function build(
config: webpack.Configuration,
{
rootDirectory,
customAppFile,
isDevelopment,
isServer,
hasSupportCss,
hasExperimentalData,
}: {
rootDirectory: string
customAppFile: string | null
isDevelopment: boolean
isServer: boolean
hasSupportCss: boolean
hasExperimentalData: boolean
}
): Promise<webpack.Configuration> {
const ctx: ConfigurationContext = {
rootDirectory,
customAppFile,
isDevelopment,
isProduction: !isDevelopment,
isServer,
isClient: !isServer,
}
const fn = pipe(
base(ctx),
experimentData(hasExperimentalData, ctx),
css(hasSupportCss, ctx)
)
return fn(config)
}
import webpack from 'webpack'
export type ConfigurationContext = {
rootDirectory: string
customAppFile: string | null
isDevelopment: boolean
isProduction: boolean
isServer: boolean
isClient: boolean
}
export type ConfigurationFn = (
a: webpack.Configuration
) => webpack.Configuration
export const pipe = <R>(...fns: Array<(a: R) => R | Promise<R>>) => (
param: R
) =>
fns.reduce(async (result: R | Promise<R>, next) => next(await result), param)
......@@ -102,6 +102,7 @@
"json5": "2.1.1",
"launch-editor": "2.2.1",
"loader-utils": "1.2.3",
"lodash.curry": "4.1.1",
"lru-cache": "5.1.1",
"mini-css-extract-plugin": "0.8.0",
"mkdirp": "0.5.1",
......@@ -161,6 +162,7 @@
"@types/fresh": "0.5.0",
"@types/json5": "0.0.30",
"@types/loader-utils": "1.1.3",
"@types/lodash.curry": "4.1.6",
"@types/lru-cache": "5.1.0",
"@types/mini-css-extract-plugin": "0.8.0",
"@types/mkdirp": "0.5.2",
......
......@@ -2722,6 +2722,18 @@
"@types/node" "*"
"@types/webpack" "*"
"@types/lodash.curry@4.1.6":
version "4.1.6"
resolved "https://registry.yarnpkg.com/@types/lodash.curry/-/lodash.curry-4.1.6.tgz#f26c490c80c92d7cbaa2300d542e89781d44b1ff"
integrity sha512-x3ctCcmOYqRrihNNnQJW6fe/yZFCgnrIa6p80AiPQRO8Jis29bBdy1dEw1FwngoF/mCZa3Bx+33fUZvOEE635Q==
dependencies:
"@types/lodash" "*"
"@types/lodash@*":
version "4.14.149"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440"
integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==
"@types/long@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef"
......@@ -4233,13 +4245,13 @@ browserify-zlib@^0.2.0:
pako "~1.0.5"
browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.3, browserslist@^4.6.4, browserslist@^4.7.1, browserslist@^4.7.3:
version "4.8.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.0.tgz#6f06b0f974a7cc3a84babc2ccc56493668e3c789"
integrity sha512-HYnxc/oLRWvJ3TsGegR0SRL/UDnknGq2s/a8dYYEO+kOQ9m9apKoS5oiathLKZdh/e9uE+/J3j92qPlGD/vTqA==
version "4.8.2"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289"
integrity sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==
dependencies:
caniuse-lite "^1.0.30001012"
electron-to-chromium "^1.3.317"
node-releases "^1.1.41"
caniuse-lite "^1.0.30001015"
electron-to-chromium "^1.3.322"
node-releases "^1.1.42"
browserstack-local@1.4.0:
version "1.4.0"
......@@ -4496,10 +4508,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001002, caniuse-lite@^1.0.30001010, caniuse-lite@^1.0.30001012:
version "1.0.30001013"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001013.tgz#da2440d4d266a17d40eb79bd19c0c8cc1d029c72"
integrity sha512-hOAXaWKuq/UVFgYawxIOdPdyMQdYcwOCDOjnZcKn7wCgFUrhP7smuNZjGLuJlPSgE6aRA4cRJ+bGSrhtEt7ZAg==
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001002, caniuse-lite@^1.0.30001010, caniuse-lite@^1.0.30001015:
version "1.0.30001015"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz#15a7ddf66aba786a71d99626bc8f2b91c6f0f5f0"
integrity sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==
capitalize@1.0.0:
version "1.0.0"
......@@ -6180,7 +6192,7 @@ ejs@^2.6.1:
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
electron-to-chromium@^1.3.317:
electron-to-chromium@^1.3.322:
version "1.3.322"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8"
integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==
......@@ -9866,6 +9878,11 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.curry@4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170"
integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA=
lodash.defaults@^4.0.1, lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
......@@ -10871,10 +10888,10 @@ node-pre-gyp@^0.13.0:
semver "^5.3.0"
tar "^4"
node-releases@^1.1.41:
version "1.1.41"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.41.tgz#57674a82a37f812d18e3b26118aefaf53a00afed"
integrity sha512-+IctMa7wIs8Cfsa8iYzeaLTFwv5Y4r5jZud+4AnfymzeEXKBCavFX0KBgzVaPVqf0ywa6PrO8/b+bPqdwjGBSg==
node-releases@^1.1.42:
version "1.1.42"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7"
integrity sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==
dependencies:
semver "^6.3.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册