Socket
Socket
Sign inDemoInstall

vite

Package Overview
Dependencies
32
Maintainers
1
Versions
552
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.10.2 to 0.10.3

2

bin/vite.js

@@ -15,3 +15,3 @@ #!/usr/bin/env node

if (argv._[0] === 'build') {
console.log(chalk.yellow('Building for production...'))
console.log('Building for production...')
require('../dist')

@@ -18,0 +18,0 @@ .build({

@@ -0,1 +1,19 @@

## [0.10.3](https://github.com/vuejs/vite/compare/v0.10.2...v0.10.3) (2020-05-05)
### Bug Fixes
* fix module entry redirect on Windows (fix [#55](https://github.com/vuejs/vite/issues/55)) ([01135fa](https://github.com/vuejs/vite/commit/01135fa1edede1f46acd7c83d18e5131ebc7cbd7))
* only log target exist when error says so ([59b8638](https://github.com/vuejs/vite/commit/59b8638d966feb7c9433911d7ba2a66617cb708c))
### Features
* add asset options into build options ([#53](https://github.com/vuejs/vite/issues/53)) ([a5c608d](https://github.com/vuejs/vite/commit/a5c608d2a0b98fc7b121d9c5eb1a4b7238dfb74b))
* public base path support ([c82a597](https://github.com/vuejs/vite/commit/c82a5976acd2ad3f39f6ee2b9efc20b1f918e687))
* support ssrBuild ([4808f41](https://github.com/vuejs/vite/commit/4808f4106fe0d71c3178c1d66272eef913efd61f))
* support template pre-processors ([b6cafee](https://github.com/vuejs/vite/commit/b6cafee5ce9e4e141bd2ba2f2646ad5db78caf0f)), closes [#17](https://github.com/vuejs/vite/issues/17)
## [0.10.2](https://github.com/vuejs/vite/compare/v0.10.1...v0.10.2) (2020-05-04)

@@ -2,0 +20,0 @@

@@ -5,14 +5,77 @@ import { InputOptions, OutputOptions, RollupOutput } from 'rollup';

export interface BuildOptions {
/**
* Project root path on file system.
* Defaults to `process.cwd()`
*/
root?: string;
/**
* Base public path when served in production.
* Defaults to /
*/
base?: string;
/**
* If true, will be importing Vue from a CDN.
* Dsiabled automatically when a local vue installation is present.
*/
cdn?: boolean;
/**
* Resolvers to map dev server public path requests to/from file system paths,
* and optionally map module ids to public path requests.
*/
resolvers?: Resolver[];
/**
* Defaults to `dist`
*/
outDir?: string;
/**
* Nest js / css / static assets under a directory under `outDir`.
* Defaults to `assets`
*/
assetsDir?: string;
/**
* Static asset files smaller than this number (in bytes) will be inlined as
* base64 strings.
* Default: 4096 (4kb)
*/
assetsInlineLimit?: number;
/**
* List files that are included in the build, but not inside project root.
* e.g. if you are building a higher level tool on top of vite and includes
* some code that will be bundled into the final build.
*/
srcRoots?: string[];
/**
* Will be passed to rollup.rollup()
* https://rollupjs.org/guide/en/#big-list-of-options
*/
rollupInputOptions?: InputOptions;
/**
* Will be passed to bundle.generate()
* https://rollupjs.org/guide/en/#big-list-of-options
*/
rollupOutputOptions?: OutputOptions;
/**
* Will be passed to rollup-plugin-vue
* https://github.com/vuejs/rollup-plugin-vue/blob/next/src/index.ts
*/
rollupPluginVueOptions?: Partial<Options>;
/**
* Whether to emit index.html
*/
emitIndex?: boolean;
/**
* Whether to emit assets other than JavaScript
*/
emitAssets?: boolean;
/**
* Whether to write bundle to disk
*/
write?: boolean;
/**
* Whether to minify output
*/
minify?: boolean;
/**
* Whether to log asset info to console
*/
silent?: boolean;

@@ -24,2 +87,13 @@ }

}
/**
* Bundles the app for production.
* Returns a Promise containing the build result.
*/
export declare function build(options?: BuildOptions): Promise<BuildResult>;
/**
* Bundles the app in SSR mode.
* - All Vue dependencies are automatically externalized
* - Imports to dependencies are compiled into require() calls
* - Templates are compiled with SSR specific optimizations.
*/
export declare function ssrBuild(options?: BuildOptions): Promise<BuildResult>;

@@ -16,24 +16,28 @@ "use strict";

const buildPluginAsset_1 = require("./buildPluginAsset");
const utils_1 = require("./utils");
const writeColors = {
[0 /* JS */]: chalk_1.default.cyan,
[1 /* CSS */]: chalk_1.default.magenta,
[2 /* ASSET */]: chalk_1.default.green,
[3 /* HTML */]: chalk_1.default.blue
};
/**
* Bundles the app for production.
* Returns a Promise containing the build result.
*/
async function build(options = {}) {
process.env.NODE_ENV = 'production';
const start = Date.now();
const { root = process.cwd(), cdn = !vueResolver_1.resolveVue(root).hasLocalVue, outDir = path_1.default.resolve(root, 'dist'), assetsDir = 'assets', resolvers = [], srcRoots = [], rollupInputOptions = {}, rollupOutputOptions = {}, rollupPluginVueOptions = {}, emitAssets = true, write = true, minify = true, silent = false } = options;
const { root = process.cwd(), base = '/', cdn = !vueResolver_1.resolveVue(root).hasLocalVue, outDir = path_1.default.resolve(root, 'dist'), assetsDir = 'assets', assetsInlineLimit = 4096, resolvers = [], srcRoots = [], rollupInputOptions = {}, rollupOutputOptions = {}, rollupPluginVueOptions = {}, emitIndex = true, emitAssets = true, write = true, minify = true, silent = false } = options;
const indexPath = emitIndex ? path_1.default.resolve(root, 'index.html') : null;
const publicBasePath = base.replace(/([^/])$/, '$1/'); // ensure ending slash
const resolvedAssetsPath = path_1.default.join(outDir, assetsDir);
const cssFileName = 'style.css';
const resolver = resolver_1.createResolver(root, resolvers);
const { htmlPlugin, renderIndex } = await buildPluginHtml_1.createBuildHtmlPlugin(indexPath, publicBasePath, assetsDir, assetsInlineLimit, resolver);
// 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;
const indexPath = path_1.default.resolve(root, 'index.html');
const cssFileName = 'style.css';
const resolvedAssetsPath = path_1.default.join(outDir, assetsDir);
let indexContent = null;
try {
indexContent = await fs_extra_1.default.readFile(indexPath, 'utf-8');
}
catch (e) {
// no index
}
const resolver = resolver_1.createResolver(root, resolvers);
srcRoots.push(root);
const bundle = await rollup({
input: path_1.default.resolve(root, 'index.html'),
preserveEntrySignatures: false,
...rollupInputOptions,

@@ -44,5 +48,5 @@ plugins: [

// vite:resolve
buildPluginResolve_1.createBuildResolvePlugin(root, cdn, srcRoots, resolver),
buildPluginResolve_1.createBuildResolvePlugin(root, cdn, [root, ...srcRoots], resolver),
// vite:html
...(indexContent ? [buildPluginHtml_1.createBuildHtmlPlugin(indexPath, indexContent)] : []),
...(htmlPlugin ? [htmlPlugin] : []),
// vue

@@ -71,5 +75,5 @@ require('rollup-plugin-vue')({

// vite:css
buildPluginCss_1.createBuildCssPlugin(root, assetsDir, cssFileName, minify),
buildPluginCss_1.createBuildCssPlugin(root, publicBasePath, assetsDir, cssFileName, minify, assetsInlineLimit),
// vite:asset
buildPluginAsset_1.createBuildAssetPlugin(assetsDir),
buildPluginAsset_1.createBuildAssetPlugin(publicBasePath, assetsDir, assetsInlineLimit),
// minify with terser

@@ -89,70 +93,29 @@ // modules: true and toplevel: true are implied with format: 'es'

});
let generatedIndex = indexContent && indexContent.replace(buildPluginHtml_1.scriptRE, '').trim();
const injectCSS = (html, filename) => {
const tag = `<link rel="stylesheet" href="/${path_1.default.posix.join(assetsDir, filename)}">`;
if (/<\/head>/.test(html)) {
return html.replace(/<\/head>/, `${tag}\n</head>`);
}
else {
return tag + '\n' + html;
}
};
const injectScript = (html, filename) => {
filename = utils_1.isExternalUrl(filename)
? filename
: `/${path_1.default.posix.join(assetsDir, filename)}`;
const tag = `<script type="module" src="${filename}"></script>`;
if (/<\/body>/.test(html)) {
return html.replace(/<\/body>/, `${tag}\n</body>`);
}
else {
return html + '\n' + tag;
}
};
// TODO handle public path for injections?
// this would also affect paths in templates and css.
if (generatedIndex) {
// inject css link
generatedIndex = injectCSS(generatedIndex, cssFileName);
if (cdn) {
// if not inlining vue, inject cdn link so it can start the fetch early
generatedIndex = injectScript(generatedIndex, vueResolver_1.resolveVue(root).cdnLink);
}
}
const indexHtml = renderIndex(root, cdn, cssFileName, output);
if (write) {
const cwd = process.cwd();
const writeFile = async (filepath, content, type) => {
await fs_extra_1.default.ensureDir(path_1.default.dirname(filepath));
await fs_extra_1.default.writeFile(filepath, content);
if (!silent) {
console.log(`${chalk_1.default.gray(`[write]`)} ${writeColors[type](path_1.default.relative(cwd, filepath))} ${(content.length / 1024).toFixed(2)}kb`);
}
};
await fs_extra_1.default.remove(outDir);
await fs_extra_1.default.ensureDir(outDir);
}
// inject / write bundle
for (const chunk of output) {
if (chunk.type === 'chunk') {
if (chunk.isEntry && generatedIndex) {
// inject chunk to html
generatedIndex = injectScript(generatedIndex, chunk.fileName);
for (const chunk of output) {
if (chunk.type === 'chunk') {
// write chunk
const filepath = path_1.default.join(resolvedAssetsPath, chunk.fileName);
await writeFile(filepath, chunk.code, 0 /* JS */);
}
// write chunk
if (write) {
else if (emitAssets) {
// write asset
const filepath = path_1.default.join(resolvedAssetsPath, chunk.fileName);
!silent &&
console.log(`write ${chalk_1.default.cyan(path_1.default.relative(process.cwd(), filepath))}`);
await fs_extra_1.default.ensureDir(path_1.default.dirname(filepath));
await fs_extra_1.default.writeFile(filepath, chunk.code);
await writeFile(filepath, chunk.source, chunk.fileName.endsWith('.css') ? 1 /* CSS */ : 2 /* ASSET */);
}
}
else if (emitAssets && write) {
// write asset
const filepath = path_1.default.join(resolvedAssetsPath, chunk.fileName);
!silent &&
console.log(`write ${chalk_1.default.magenta(path_1.default.relative(process.cwd(), filepath))}`);
await fs_extra_1.default.ensureDir(path_1.default.dirname(filepath));
await fs_extra_1.default.writeFile(filepath, chunk.source);
}
}
if (write) {
// write html
if (generatedIndex) {
const indexOutPath = path_1.default.join(outDir, 'index.html');
!silent &&
console.log(`write ${chalk_1.default.green(path_1.default.relative(process.cwd(), indexOutPath))}`);
await fs_extra_1.default.writeFile(indexOutPath, generatedIndex);
if (indexHtml && emitIndex) {
await writeFile(path_1.default.join(outDir, 'index.html'), indexHtml, 3 /* HTML */);
}

@@ -164,5 +127,54 @@ }

assets: output,
html: generatedIndex || ''
html: indexHtml
};
}
exports.build = build;
/**
* Bundles the app in SSR mode.
* - All Vue dependencies are automatically externalized
* - Imports to dependencies are compiled into require() calls
* - Templates are compiled with SSR specific optimizations.
*/
async function ssrBuild(options = {}) {
const { rollupInputOptions, rollupOutputOptions, rollupPluginVueOptions } = options;
return build({
...options,
rollupPluginVueOptions: {
...rollupPluginVueOptions,
target: 'node'
},
rollupInputOptions: {
...rollupInputOptions,
external: resolveExternal(rollupInputOptions && rollupInputOptions.external)
},
rollupOutputOptions: {
...rollupOutputOptions,
format: 'cjs',
exports: 'named'
},
emitIndex: false,
emitAssets: false,
minify: false
});
}
exports.ssrBuild = ssrBuild;
function resolveExternal(userExternal) {
const required = ['vue', /^@vue\//];
if (!userExternal) {
return required;
}
if (Array.isArray(userExternal)) {
return [...required, ...userExternal];
}
else if (typeof userExternal === 'function') {
return (src, importer, isResolved) => {
if (src === 'vue' || /^@vue\//.test(src)) {
return true;
}
return userExternal(src, importer, isResolved);
};
}
else {
return [...required, userExternal];
}
}
/// <reference types="node" />
import { Plugin, OutputBundle } from 'rollup';
export declare const getAssetPublicPath: (id: string, assetsDir: string) => Promise<{
interface AssetCacheEntry {
content: Buffer;
fileName: string;
url: string;
}>;
}
export declare const resolveAsset: (id: string, publicBase: string, assetsDir: string, inlineLimit: number) => Promise<AssetCacheEntry>;
export declare const registerAssets: (assets: Map<string, string>, bundle: OutputBundle) => void;
export declare const createBuildAssetPlugin: (assetsDir: string) => Plugin;
export declare const createBuildAssetPlugin: (publicBase: string, assetsDir: string, inlineLimit: number) => Plugin;
export {};

@@ -13,16 +13,17 @@ "use strict";

const debug = require('debug')('vite:build:asset');
// TODO make this configurable
const inlineThreshold = 10000;
exports.getAssetPublicPath = async (id, assetsDir) => {
const assetResolveCache = new Map();
exports.resolveAsset = async (id, publicBase, assetsDir, inlineLimit) => {
const cached = assetResolveCache.get(id);
if (cached) {
return cached;
}
const ext = path_1.default.extname(id);
const baseName = path_1.default.basename(id, ext);
const resolvedFileName = `${baseName}.${hash_sum_1.default(id)}${ext}`;
let url = slash_1.default(path_1.default.join('/', assetsDir, resolvedFileName));
let url = slash_1.default(path_1.default.join(publicBase, assetsDir, resolvedFileName));
const content = await fs_extra_1.default.readFile(id);
if (!id.endsWith(`.svg`)) {
if (content.length < inlineThreshold) {
url = `data:${mime_types_1.default.lookup(id)};base64,${content.toString('base64')}`;
}
if (!id.endsWith(`.svg`) && content.length < inlineLimit) {
url = `data:${mime_types_1.default.lookup(id)};base64,${content.toString('base64')}`;
}
return {
const resolved = {
content,

@@ -32,2 +33,4 @@ fileName: resolvedFileName,

};
assetResolveCache.set(id, resolved);
return resolved;
};

@@ -44,3 +47,3 @@ exports.registerAssets = (assets, bundle) => {

};
exports.createBuildAssetPlugin = (assetsDir) => {
exports.createBuildAssetPlugin = (publicBase, assetsDir, inlineLimit) => {
const assets = new Map();

@@ -51,3 +54,3 @@ return {

if (utils_1.isStaticAsset(id)) {
const { fileName, content, url } = await exports.getAssetPublicPath(id, assetsDir);
const { fileName, content, url } = await exports.resolveAsset(id, publicBase, assetsDir, inlineLimit);
assets.set(fileName, content);

@@ -54,0 +57,0 @@ debug(`${id} -> ${url}`);

import { Plugin } from 'rollup';
export declare const createBuildCssPlugin: (root: string, assetsDir: string, cssFileName: string, minify: boolean) => Plugin;
export declare const createBuildCssPlugin: (root: string, publicBase: string, assetsDir: string, cssFileName: string, minify: boolean, inlineLimit: number) => Plugin;

@@ -10,5 +10,5 @@ "use strict";

const utils_1 = require("./utils");
const debug = require('debug')('vite:css');
const debug = require('debug')('vite:build:css');
const urlRE = /(url\(\s*['"]?)([^"')]+)(["']?\s*\))/;
exports.createBuildCssPlugin = (root, assetsDir, cssFileName, minify) => {
exports.createBuildCssPlugin = (root, publicBase, assetsDir, cssFileName, minify, inlineLimit) => {
const styles = new Map();

@@ -36,3 +36,3 @@ const assets = new Map();

const file = path_1.default.join(fileDir, rawUrl);
const { fileName, content, url } = await buildPluginAsset_1.getAssetPublicPath(file, assetsDir);
const { fileName, content, url } = await buildPluginAsset_1.resolveAsset(file, publicBase, assetsDir, inlineLimit);
assets.set(fileName, content);

@@ -39,0 +39,0 @@ debug(`url(${rawUrl}) -> url(${url})`);

import { Plugin } from 'rollup';
export declare const scriptRE: RegExp;
export declare const createBuildHtmlPlugin: (indexPath: string, indexContent: string) => Plugin;
import { InternalResolver } from './resolver';
export declare const createBuildHtmlPlugin: (indexPath: string | null, publicBasePath: string, assetsDir: string, inlineLimit: number, resolver: InternalResolver) => Promise<{
renderIndex: (...args: any[]) => string;
htmlPlugin: null;
} | {
renderIndex: (root: string, cdn: boolean, cssFileName: string, bundleOutput: [import("rollup").OutputChunk, ...(import("rollup").OutputAsset | import("rollup").OutputChunk)[]]) => string;
htmlPlugin: Plugin;
}>;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scriptRE = /<script\b([^>]*)>([\s\S]*?)<\/script>/gm;
const srcRE = /\bsrc=(?:"([^"]+)"|'([^']+)'|([^'"\s]+)\b)/;
exports.createBuildHtmlPlugin = (indexPath, indexContent) => {
return {
const path_1 = __importDefault(require("path"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const utils_1 = require("./utils");
const vueResolver_1 = require("./vueResolver");
const buildPluginAsset_1 = require("./buildPluginAsset");
const compiler_dom_1 = require("@vue/compiler-dom");
const magic_string_1 = __importDefault(require("magic-string"));
exports.createBuildHtmlPlugin = async (indexPath, publicBasePath, assetsDir, inlineLimit, resolver) => {
if (!indexPath || !(await fs_extra_1.default.pathExists(indexPath))) {
return {
renderIndex: (...args) => '',
htmlPlugin: null
};
}
const rawHtml = await fs_extra_1.default.readFile(indexPath, 'utf-8');
let { html: processedHtml, js } = await compileHtml(rawHtml, publicBasePath, assetsDir, inlineLimit, resolver);
const htmlPlugin = {
name: 'vite:html',
load(id) {
async load(id) {
if (id === indexPath) {
let script = '';
let match;
while ((match = exports.scriptRE.exec(indexContent))) {
return js;
}
}
};
const injectCSS = (html, filename) => {
const tag = `<link rel="stylesheet" href="${publicBasePath}${path_1.default.posix.join(assetsDir, filename)}">`;
if (/<\/head>/.test(html)) {
return html.replace(/<\/head>/, `${tag}\n</head>`);
}
else {
return tag + '\n' + html;
}
};
const injectScript = (html, filename) => {
filename = utils_1.isExternalUrl(filename)
? filename
: `${publicBasePath}${path_1.default.posix.join(assetsDir, filename)}`;
const tag = `<script type="module" src="${filename}"></script>`;
if (/<\/body>/.test(html)) {
return html.replace(/<\/body>/, `${tag}\n</body>`);
}
else {
return html + '\n' + tag;
}
};
const renderIndex = (root, cdn, cssFileName, bundleOutput) => {
// inject css link
processedHtml = injectCSS(processedHtml, cssFileName);
// if not inlining vue, inject cdn link so it can start the fetch early
if (cdn) {
processedHtml = injectScript(processedHtml, vueResolver_1.resolveVue(root).cdnLink);
}
// inject js entry chunks
for (const chunk of bundleOutput) {
if (chunk.type === 'chunk' && chunk.isEntry) {
processedHtml = injectScript(processedHtml, chunk.fileName);
}
}
return processedHtml;
};
return {
renderIndex,
htmlPlugin
};
};
// this extends the config in @vue/compiler-sfc with <link href>
const assetAttrsConfig = {
link: ['href'],
video: ['src', 'poster'],
source: ['src'],
img: ['src'],
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href']
};
// compile index.html to a JS module, importing referenced assets
// and scripts
const compileHtml = async (html, publicBasePath, assetsDir, inlineLimit, resolver) => {
const ast = compiler_dom_1.parse(html);
let js = '';
const s = new magic_string_1.default(html);
const assetUrls = [];
const viteHtmlTrasnfrom = (node, context) => {
if (node.type === 1 /* ELEMENT */) {
if (node.tag === 'script') {
const srcAttr = node.props.find((p) => p.type === 6 /* ATTRIBUTE */ && p.name === 'src');
if (srcAttr && srcAttr.value) {
// <script type="module" src="..."/>
// add it as an import
const tagAttr = match[1];
const srcMatch = tagAttr && tagAttr.match(srcRE);
if (srcMatch) {
script += `\nimport "${srcMatch[1] || srcMatch[2] || srcMatch[3]}"\n`;
}
js += `\nimport ${JSON.stringify(srcAttr.value.content)}`;
}
else if (node.children.length) {
// <script type="module">...</script>
// add its content
script += match[2];
// TODO: if there are multiple inline module scripts on the page,
// they should technically be turned into separate modules, but
// it's hard to imagine any reason for anyone to do that.
js += `\n` + node.children[0].content.trim() + `\n`;
}
return script;
// remove the script tag from the html. we are going to inject new
// ones in the end.
s.remove(node.loc.start.offset, node.loc.end.offset);
}
// For asset references in index.html, also generate an import
// statement for each - this will be handled by the asset plugin
const assetAttrs = assetAttrsConfig[node.tag];
if (assetAttrs) {
for (const p of node.props) {
if (p.type === 6 /* ATTRIBUTE */ &&
p.value &&
assetAttrs.includes(p.name) &&
!utils_1.isExternalUrl(p.value.content)) {
const url = utils_1.cleanUrl(p.value.content);
js += `\nimport ${JSON.stringify(url)}`;
if (utils_1.isStaticAsset(url)) {
assetUrls.push(p);
}
}
}
}
}
};
compiler_dom_1.transform(ast, {
nodeTransforms: [viteHtmlTrasnfrom]
});
// for each encountered asset url, rewrite original html so that it
// references the post-build location.
for (const attr of assetUrls) {
const value = attr.value;
const { url } = await buildPluginAsset_1.resolveAsset(resolver.requestToFile(value.content), publicBasePath, assetsDir, inlineLimit);
s.overwrite(value.loc.start.offset, value.loc.end.offset, url);
}
return {
html: s.toString(),
js
};
};

@@ -12,2 +12,3 @@ "use strict";

const utils_1 = require("./utils");
const slash_1 = __importDefault(require("slash"));
const debug = require('debug')('vite:resolve');

@@ -51,3 +52,3 @@ const idToEntryMap = new Map();

debug(`(cached redirect) ${id} -> ${cachedEntry}`);
return ctx.redirect(path_1.default.join(ctx.path, cachedEntry));
return ctx.redirect(slash_1.default(path_1.default.join(ctx.path, cachedEntry)));
}

@@ -68,3 +69,3 @@ // resolve from web_modules

if (entryPoint) {
return ctx.redirect(path_1.default.join(ctx.path, entryPoint));
return ctx.redirect(slash_1.default(path_1.default.join(ctx.path, entryPoint)));
}

@@ -71,0 +72,0 @@ // resolve from node_modules

@@ -165,3 +165,2 @@ "use strict";

transformAssetUrls: {
// @ts-ignore
base: path_1.default.posix.dirname(publicPath)

@@ -172,3 +171,5 @@ },

runtimeModuleName: '/@modules/vue'
}
},
preprocessLang: template.lang,
preprocessCustomRequire: (id) => require(resolve_from_1.default(root, id))
});

@@ -175,0 +176,0 @@ if (errors.length) {

@@ -13,3 +13,3 @@ "use strict";

exports.isExternalUrl = (url) => httpRE.test(url);
const imageRE = /\.(png|jpe?g|gif|svg)(\?.*)?$/;
const imageRE = /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/;
const mediaRE = /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/;

@@ -16,0 +16,0 @@ const fontsRE = /\.(woff2?|eot|ttf|otf)(\?.*)?$/i;

{
"name": "vite",
"version": "0.10.2",
"version": "0.10.3",
"license": "MIT",

@@ -82,3 +82,3 @@ "author": "Evan You",

"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-vue": "^6.0.0-alpha.7",
"rollup-plugin-vue": "^6.0.0-alpha.8",
"slash": "^3.0.0",

@@ -85,0 +85,0 @@ "vue": "^3.0.0-beta.9",

@@ -5,2 +5,11 @@ # vite ⚡

- Super fast cold server start
- Super fast hot module replacement (HMR)
- True on-demand compilation
- More details in [How and Why](#how-and-why)
## Status
Still experimental, but we intend to make it suitable for production.
## Getting Started

@@ -24,28 +33,2 @@

## How is This Different from a Bundler-based Setup?
The primary difference is that for `vite` there is no bundling during development. The ES Import syntax in your source code is served directly to the browser, and the browser parses them via native `<script module>` support, making HTTP requests for each import. The dev server intercepts the requests and performs code transforms if necessary. For example, an import to a `*.vue` file is compiled on the fly right before it's sent back to the browser.
There are a few advantages of this approach:
- Since there is no bundling work to be done, the server cold start is extremely fast.
- Code is compiled on demand, so only code actually imported on the current screen is compiled. You don't have to wait until your entire app to be bundled to start developing. This can be a huge difference in apps with dozens of screens.
- Hot module replacement (HMR) performance is decoupled from the total number of modules. This makes HMR consistently fast no matter how big your app is.
Full page reload could be slightly slower than a bundler-based setup, since native ES imports result in network waterfalls with deep import chains. However since this is local development, the difference should be trivial compared to actual compilation time. (There is no compile cost on page reload since already compiled files are cached in memory.)
Finally, because compilation is still done in Node, it can technically support any code transforms a bundler can, and nothing prevents you from eventually bundling the code for production. In fact, `vite` provides a `vite build` command to do exactly that so the app doesn't suffer from network waterfall in production.
`vite` is highly experimental at this stage and is not suitable for production use, but we hope to one day make it so.
## How is This Different from [es-dev-server](https://open-wc.org/developing/es-dev-server.html)?
`es-dev-server` is a great project and we did take some inspiration from it when refactoring `vite` in the early stages. That said, here is why `vite` is different from `es-dev-server` and why we didn't just implement `vite` as a middleware for `es-dev-server`:
- `vite` supports Hot Module Replacement, which surgically updates the updated module without reloading the page. This is a fundamental difference in terms of development experience. `es-dev-server` internals is a bit too opaque to get this working nicely via a middleware.
- `vite` aims to be a single tool that integrates both the dev and the build process. You can use `vite` to both serve and bundle the same source code, with zero configuration.
## Browser Support

@@ -59,2 +42,13 @@

- [Bare Module Resolving](#bare-module-resolving)
- [Hot Module Replacement](#hot-module-replacement)
- [CSS / JSON Importing](#css--json-importing)
- [Asset URL Handling](#asset-url-handling)
- [PostCSS](#postcss)
- [CSS Modules](#css-modules)
- [CSS Pre-processors](#css-pre-processors)
- [Production Build](#production-build)
`vite` tries to mirror the default configuration in [vue-cli](http://cli.vuejs.org/) as much as possible. If you've used `vue-cli` or other webpack-based boilerplates before, you should feel right at home. That said, do expect things to be different here and there.
### Bare Module Resolving

@@ -126,8 +120,10 @@

### Relative Asset URL Handling
### Asset URL Handling
You can reference static assets in your `*.vue` templates, styles and plain `.css` files using relative URLs based on the asset's location to the source file on your file system. This is similar to the behavior you are used to if you have used `vue-cli` or webpack's `file-loader`.
You can reference static assets in your `*.vue` templates, styles and plain `.css` files either using absolute public paths (based on project root) or relative paths (based on your file system). The latter is similar to the behavior you are used to if you have used `vue-cli` or webpack's `file-loader`.
Referenced assets will be copied to the dist folder with a hashed file name in the production build.
There is no conventional `public` directory. All referenced assets, including those using absolute paths, will be copied to the dist folder with a hashed file name in the production build. Never-referenced assets will not be copied.
Similar to `vue-cli`, image assets smaller than 4kb will be base64 inlined.
### PostCSS

@@ -156,6 +152,8 @@

### Building for Production
### Production Build
Starting with version `^0.5.0`, you can run `vite build` to bundle the app and deploy it for production.
`vite` does utilize bundling for production builds, because native ES module imports result in waterfall network requests that are simply too punishing for page load time in production.
You can run `vite build` to bundle the app.
- `vite build --root dir`: build files in the target directory instead of current working directory.

@@ -242,7 +240,36 @@

## How and Why
### How is This Different from `vue-cli` or other Bundler-based Solutions?
The primary difference is that for `vite` there is no bundling during development. The ES Import syntax in your source code is served directly to the browser, and the browser parses them via native `<script module>` support, making HTTP requests for each import. The dev server intercepts the requests and performs code transforms if necessary. For example, an import to a `*.vue` file is compiled on the fly right before it's sent back to the browser.
There are a few advantages of this approach:
- Since there is no bundling work to be done, the server cold start is extremely fast.
- Code is compiled on demand, so only code actually imported on the current screen is compiled. You don't have to wait until your entire app to be bundled to start developing. This can be a huge difference in apps with dozens of screens.
- Hot module replacement (HMR) performance is decoupled from the total number of modules. This makes HMR consistently fast no matter how big your app is.
Full page reload could be slightly slower than a bundler-based setup, since native ES imports result in network waterfalls with deep import chains. However since this is local development, the difference should be trivial compared to actual compilation time. (There is no compile cost on page reload since already compiled files are cached in memory.)
Finally, because compilation is still done in Node, it can technically support any code transforms a bundler can, and nothing prevents you from eventually bundling the code for production. In fact, `vite` provides a `vite build` command to do exactly that so the app doesn't suffer from network waterfall in production.
### How is This Different from [es-dev-server](https://open-wc.org/developing/es-dev-server.html)?
`es-dev-server` is a great project and we did take some inspiration from it when refactoring `vite` in the early stages. That said, here is why `vite` is different from `es-dev-server` and why we didn't just implement `vite` as a middleware for `es-dev-server`:
- `vite` supports Hot Module Replacement, which surgically updates the updated module without reloading the page. This is a fundamental difference in terms of development experience. `es-dev-server` internals is a bit too opaque to get this working nicely via a middleware.
- `vite` aims to be a single tool that integrates both the dev and the build process. You can use `vite` to both serve and bundle the same source code, with zero configuration.
- `vite` is more opinionated on how certain types of imports are handled, e.g. `.css` and static assets. The handling is similar to `vue-cli` for obvious reasons.
## TODOs
- Public base path support
- Config file support (custom import maps and plugins)
- Support TypeScript / Flow /(P)React JSX via [Sucrase](https://github.com/alangpierce/sucrase)
- Support TypeScript / Flow /(P)React JSX via [Sucrase](https://github.com/alangpierce/sucrase) or [esbuild](https://github.com/evanw/esbuild)

@@ -249,0 +276,0 @@ ## Trivia

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc