Skip to content

Commit

Permalink
feat: automatically optimize deps on server start
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed May 13, 2020
1 parent e6bfd20 commit 49a44b6
Show file tree
Hide file tree
Showing 18 changed files with 370 additions and 321 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
},
"dependencies": {
"@babel/parser": "^7.9.4",
"@rollup/plugin-commonjs": "11.0.2",
"@rollup/plugin-commonjs": "~11.0.0",
"@rollup/plugin-json": "^4.0.3",
"@rollup/plugin-node-resolve": "^7.1.3",
"@types/koa": "^2.11.3",
Expand Down Expand Up @@ -83,7 +83,6 @@
"postcss": "^7.0.28",
"postcss-load-config": "^2.1.0",
"postcss-modules": "^2.0.0",
"resolve-from": "^5.0.0",
"rollup": "^2.7.2",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^6.0.0-alpha.10",
Expand Down
5 changes: 0 additions & 5 deletions playground/TestModuleResolve.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
<div class="module-resolve-optimize" :class="optResolve">
optimized {{ optResolve }}
</div>
<div class="module-resolve-web" :class="web_modules">
web_modules {{ web_modules }}
</div>
<div class="index-resolve" :class="indexResolve">
directory index resolve: {{ indexResolve }}
</div>
Expand All @@ -19,7 +16,6 @@
import { createRouter } from 'vue-router'
import { createStore } from 'vuex'
import { add } from 'lodash-es'
import { dep } from 'web-modules-dep'
import { foo } from './util'
export default {
Expand All @@ -28,7 +24,6 @@ export default {
router: typeof createRouter === 'function' ? 'ok' : 'error',
store: typeof createStore === 'function' ? 'ok' : 'error',
optResolve: typeof add === 'function' ? 'ok' : 'error',
web_modules: dep() ? 'ok' : 'error',
indexResolve: foo() ? 'ok' : 'error'
}
}
Expand Down
3 changes: 0 additions & 3 deletions playground/web_modules/web-modules-dep.js

This file was deleted.

10 changes: 1 addition & 9 deletions src/node/build/buildPluginResolve.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { Plugin } from 'rollup'
import fs from 'fs-extra'
import { hmrClientId } from '../server/serverPluginHmr'
import { InternalResolver } from '../resolver'
import { resolveVue } from '../utils/resolveVue'
import {
resolveWebModule,
resolveOptimizedModule
} from '../server/serverPluginModuleResolve'
import { InternalResolver, resolveOptimizedModule } from '../resolver'

const debug = require('debug')('vite:build:resolve')

Expand Down Expand Up @@ -38,10 +34,6 @@ export const createBuildResolvePlugin = (
if (optimizedModule) {
return optimizedModule
}
const webModulePath = resolveWebModule(root, id)
if (webModulePath) {
return webModulePath
}
}
// fallback to node-resolve
const resolved = this.resolve(id, importer, { skipSelf: true })
Expand Down
135 changes: 96 additions & 39 deletions src/node/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import path from 'path'
import fs from 'fs-extra'
import chalk from 'chalk'
import { Ora } from 'ora'
import resolve from 'resolve-from'
import { rollup as Rollup, RollupOutput, ExternalOption } from 'rollup'
import { createResolver, supportedExts } from '../resolver'
import { resolveFrom } from '../utils'
import { rollup as Rollup, RollupOutput, ExternalOption, Plugin } from 'rollup'
import { createResolver, supportedExts, InternalResolver } from '../resolver'
import { createBuildResolvePlugin } from './buildPluginResolve'
import { createBuildHtmlPlugin } from './buildPluginHtml'
import { createBuildCssPlugin } from './buildPluginCss'
Expand Down Expand Up @@ -36,6 +36,84 @@ const writeColors = {
[WriteType.SOURCE_MAP]: chalk.gray
}

const PACKAGES_TO_AUTO_DETECT_EXPORTS = [
path.join('react', 'index.js'),
path.join('react-dom', 'index.js'),
'react-is',
'prop-types',
'scheduler',
'rxjs',
'exenv',
'body-scroll-lock'
]

function detectExports(root: string, id: string): string[] | undefined {
try {
const fileLoc = resolveFrom(root, id)
if (fs.existsSync(fileLoc)) {
return Object.keys(require(fileLoc)).filter((e) => e[0] !== '_')
}
} catch (err) {
// ignore
}
}

/**
* Creates non-application specific plugins that are shared between the main
* app and the dependencies. This is used by the `optimize` command to
* pre-bundle dependencies.
*/
export async function createBaseRollupPlugins(
root: string,
resolver: InternalResolver,
options: BuildConfig
): Promise<Plugin[]> {
const { rollupInputOptions = {}, transforms = [] } = options

// TODO allow user to configure known named exports
const knownNamedExports: Record<string, string[]> = {}
for (const id of PACKAGES_TO_AUTO_DETECT_EXPORTS) {
knownNamedExports[id] =
knownNamedExports[id] || detectExports(root, id) || []
}

return [
// user plugins
...(rollupInputOptions.plugins || []),
// vite:resolve
createBuildResolvePlugin(root, resolver),
// vite:esbuild
await createEsbuildPlugin(options.minify === 'esbuild', options.jsx),
// vue
require('rollup-plugin-vue')({
...options.rollupPluginVueOptions,
transformAssetUrls: {
includeAbsolute: true
},
preprocessStyles: true,
preprocessCustomRequire: (id: string) => require(resolveFrom(root, id)),
compilerOptions: options.vueCompilerOptions
}),
require('@rollup/plugin-json')({
preferConst: true,
indent: ' ',
compact: false,
namedExports: true
}),
// user transforms
...(transforms.length ? [createBuildJsTransformPlugin(transforms)] : []),
require('@rollup/plugin-node-resolve')({
rootDir: root,
extensions: supportedExts,
preferBuiltins: false
}),
require('@rollup/plugin-commonjs')({
extensions: ['.js', '.cjs'],
namedExports: knownNamedExports
})
].filter(Boolean)
}

/**
* Bundles the app for production.
* Returns a Promise containing the build result.
Expand All @@ -61,11 +139,8 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
alias = {},
transforms = [],
resolvers = [],
vueCompilerOptions,
rollupInputOptions = {},
rollupOutputOptions = {},
rollupPluginVueOptions = {},
jsx = {},
emitIndex = true,
emitAssets = true,
write = true,
Expand Down Expand Up @@ -101,46 +176,33 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
resolver
)

const basePlugins = await createBaseRollupPlugins(root, resolver, options)

// lazy require rollup so that we don't load it when only using the dev server
// importing it just for the types
const rollup = require('rollup').rollup as typeof Rollup
const bundle = await rollup({
input: path.resolve(root, 'index.html'),
preserveEntrySignatures: false,
treeshake: { moduleSideEffects: 'no-external' },
onwarn(warning, warn) {
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
warn(warning)
}
},
...rollupInputOptions,
plugins: [
// user plugins
...(rollupInputOptions.plugins || []),
// vite:resolve
createBuildResolvePlugin(root, resolver),
...basePlugins,
// vite:html
...(htmlPlugin ? [htmlPlugin] : []),
// vite:esbuild
await createEsbuildPlugin(minify === 'esbuild', jsx),
// vue
require('rollup-plugin-vue')({
...rollupPluginVueOptions,
transformAssetUrls: {
includeAbsolute: true
},
preprocessStyles: true,
preprocessCustomRequire: (id: string) => require(resolve(root, id)),
compilerOptions: vueCompilerOptions
}),
require('@rollup/plugin-json')(),
// user transforms
...(transforms.length ? [createBuildJsTransformPlugin(transforms)] : []),
require('@rollup/plugin-node-resolve')({
rootDir: root,
extensions: supportedExts
}),
htmlPlugin,
// we use a custom replacement plugin because @rollup/plugin-replace
// performs replacements twice, once at transform and once at renderChunk
// - which makes it impossible to exclude Vue templates from it since
// Vue templates are compiled into js and included in chunks.
createReplacePlugin(
{
'process.env.NODE_ENV': '"production"',
'process.env.': `({}).`,
__DEV__: 'false',
__BASE__: JSON.stringify(publicBasePath)
},
Expand All @@ -167,15 +229,10 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
// this is the default which has better compression, but slow
// the user can opt-in to use esbuild which is much faster but results
// in ~8-10% larger file size.
...(minify && minify !== 'esbuild'
? [require('rollup-plugin-terser').terser()]
: [])
],
onwarn(warning, warn) {
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
warn(warning)
}
}
minify && minify !== 'esbuild'
? require('rollup-plugin-terser').terser()
: undefined
]
})

const { output } = await bundle.generate({
Expand Down
4 changes: 3 additions & 1 deletion src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ async function runServe(
open?: boolean
}
) {
await require('../dist').optimizeDeps(options)

const server = require('../dist').createServer(options)

let port = options.port || 3000
Expand Down Expand Up @@ -167,7 +169,7 @@ async function runBuild(options: UserConfig) {

async function runOptimize(options: UserConfig) {
try {
await require('../dist').optimize(options)
await require('../dist').optimizeDeps(options)
process.exit(0)
} catch (err) {
console.error(chalk.red(`[vite] Dep optimization errored out.`))
Expand Down
Loading

0 comments on commit 49a44b6

Please sign in to comment.