Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable strict types mode #227

Merged
merged 1 commit into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,6 @@ export default function loadConfig(cliFlags?: SnowpackConfig) {

// resolve --dest relative to cwd
function normalizeDest(config: SnowpackConfig) {
config.installOptions.dest = path.resolve(process.cwd(), config.installOptions.dest);
config.installOptions.dest = path.resolve(process.cwd(), config.installOptions.dest!);
return config;
}
77 changes: 38 additions & 39 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import babelPresetEnv from '@babel/preset-env';
import isNodeBuiltin from 'is-builtin-module';
import validatePackageName from 'validate-npm-package-name';

import * as rollup from 'rollup';
import {rollup, InputOptions, OutputOptions, Plugin, RollupError} from 'rollup';
import rollupPluginNodeResolve from '@rollup/plugin-node-resolve';
import rollupPluginCommonjs from '@rollup/plugin-commonjs';
import {terser as rollupPluginTerser} from 'rollup-plugin-terser';
Expand All @@ -26,7 +26,7 @@ import {
DependencyStats,
} from './rollup-plugin-dependency-info.js';
import {scanImports, scanDepList, InstallTarget} from './scan-imports.js';
import {resolveDependencyManifest, MISSING_PLUGIN_SUGGESTIONS} from './util.js';
import {resolveDependencyManifest, truthy, MISSING_PLUGIN_SUGGESTIONS} from './util.js';

import zlib from 'zlib';

Expand All @@ -38,8 +38,8 @@ export interface DependencyLoc {
const ALWAYS_SHOW_ERRORS = new Set(['react', 'react-dom']);
const cwd = process.cwd();
const banner = chalk.bold(`snowpack`) + ` installing... `;
const installResults = [];
let dependencyStats: DependencyStatsOutput = null;
const installResults: [string, boolean][] = [];
let dependencyStats: DependencyStatsOutput | null = null;
let spinner = ora(banner);
let spinnerHasError = false;

Expand All @@ -65,20 +65,20 @@ ${chalk.bold('Options:')}
);
}

async function generateHashFromFile(targetLoc) {
async function generateHashFromFile(targetLoc: string) {
const longHash = await hasha.fromFile(targetLoc, {algorithm: 'md5'});
return longHash.slice(0, 10);
return longHash!.slice(0, 10);
}

function formatInstallResults(skipFailures): string {
function formatInstallResults(skipFailures: boolean): string {
return installResults
.map(([d, yn]) => (yn ? chalk.green(d) : skipFailures ? chalk.dim(d) : chalk.red(d)))
.join(', ');
}

function formatSize(size) {
function formatSize(size: number) {
const kb = Math.round((size / 1000) * 100) / 100;
let color;
let color: 'green' | 'yellow' | 'red';
if (kb < 15) {
color = 'green';
} else if (kb < 30) {
Expand All @@ -89,7 +89,7 @@ function formatSize(size) {
return chalk[color](`${kb} KB`);
}

function formatDelta(delta) {
function formatDelta(delta: number) {
const kb = Math.round(delta * 100) / 100;
const color = delta > 0 ? 'red' : 'green';
return chalk[color](`Δ ${delta > 0 ? '+' : ''}${kb} KB`);
Expand All @@ -105,25 +105,24 @@ function formatFileInfo(
const filePath = fs.existsSync(commonPath) ? commonPath : path.join(cwd, 'web_modules', filename);
const fileContent = fs.readFileSync(filePath, 'utf-8');
const gzipSize = zlib.gzipSync(fileContent).byteLength;
let brSize;
let brSize: number;
if (zlib.brotliCompressSync) {
brSize = zlib.brotliCompressSync(fileContent).byteLength;
}
const lineGlyph = chalk.dim(isLastFile ? '└─' : '├─');
const lineName = filename.padEnd(padEnd);
const fileStat = chalk.dim('[') + formatSize(stats.size) + chalk.dim(']');
const gzipStat = ' [gzip: ' + formatSize(gzipSize) + ']';
const brotliStat = ' [brotli: ' + formatSize(brSize) + ']';
const brotliStat = ' [brotli: ' + formatSize(brSize!) + ']';
const lineSize = zlib.brotliCompressSync ? fileStat + gzipStat + brotliStat : fileStat + gzipStat;
const lineDelta = stats.delta ? chalk.dim(' [') + formatDelta(stats.delta) + chalk.dim(']') : '';
return ` ${lineGlyph} ${lineName} ${lineSize}${lineDelta}`;
}

function formatFiles(files: [string, DependencyStats][], title: string) {
const strippedFiles = files.map(([filename, stats]) => [
filename.replace(/^common\//, ''),
stats,
]) as [string, DependencyStats][];
const strippedFiles = files.map(
([filename, stats]) => [filename.replace(/^common\//, ''), stats] as const,
);
const maxFileNameLength = strippedFiles.reduce(
(max, [filename]) => Math.max(filename.length, max),
0,
Expand All @@ -138,7 +137,7 @@ ${strippedFiles

function formatDependencyStats(): string {
let output = '';
const {direct, common} = dependencyStats;
const {direct, common} = dependencyStats!;
const allDirect = Object.entries(direct);
const allCommon = Object.entries(common);
output += formatFiles(allDirect, 'web_modules/');
Expand All @@ -148,7 +147,7 @@ function formatDependencyStats(): string {
return `\n${output}\n`;
}

function logError(msg) {
function logError(msg: string) {
if (!spinnerHasError) {
spinner.stopAndPersist({symbol: chalk.cyan('⠼')});
}
Expand Down Expand Up @@ -293,7 +292,7 @@ export async function install(
rollup: userDefinedRollup,
} = config;

const knownNamedExports = {...namedExports};
const knownNamedExports = {...namedExports!};
for (const filePath of PACKAGES_TO_AUTO_DETECT_EXPORTS) {
knownNamedExports[filePath] = knownNamedExports[filePath] || detectExports(filePath) || [];
}
Expand All @@ -304,8 +303,8 @@ export async function install(
const allInstallSpecifiers = new Set(installTargets.map(dep => dep.specifier));
const depObject: {[targetName: string]: string} = {};
const assetObject: {[targetName: string]: string} = {};
const importMap = {};
const installTargetsMap = {};
const importMap: {[installSpecifier: string]: string} = {};
const installTargetsMap: {[targetLoc: string]: InstallTarget[]} = {};
const skipFailures = !isExplicit;
for (const installSpecifier of allInstallSpecifiers) {
try {
Expand Down Expand Up @@ -349,7 +348,7 @@ export async function install(
return false;
}

const inputOptions = {
const inputOptions: InputOptions = {
input: depObject,
external: externalPackages,
plugins: [
Expand All @@ -359,7 +358,7 @@ export async function install(
'process.env.NODE_ENV': isOptimized ? '"production"' : '"development"',
}),
rollupPluginNodeResolve({
mainFields: ['browser:module', 'module', 'browser', !isStrict && 'main'].filter(Boolean),
mainFields: ['browser:module', 'module', 'browser', !isStrict && 'main'].filter(truthy),
modulesOnly: isStrict, // Default: false
extensions: ['.mjs', '.cjs', '.js', '.json'], // Default: [ '.mjs', '.js', '.json', '.node' ]
// whether to prefer built-in modules (e.g. `fs`, `path`) or local ones with the same names
Expand Down Expand Up @@ -398,9 +397,9 @@ export async function install(
!!isOptimized && rollupPluginTreeshakeInputs(installTargets),
!!isOptimized && rollupPluginTerser(),
!!withStats && rollupPluginDependencyStats(info => (dependencyStats = info)),
...userDefinedRollup.plugins, // load user-defined plugins last
...userDefinedRollup!.plugins!, // load user-defined plugins last
],
onwarn: ((warning, warn) => {
onwarn(warning, warn) {
if (warning.code === 'UNRESOLVED_IMPORT') {
logError(
`'${warning.source}' is imported by '${warning.importer}', but could not be resolved.`,
Expand All @@ -424,21 +423,21 @@ export async function install(
return;
}
warn(warning);
}) as any,
},
};
const outputOptions = {
const outputOptions: OutputOptions = {
dir: destLoc,
format: 'esm' as 'esm',
sourcemap: sourceMap === undefined ? isOptimized : sourceMap,
exports: 'named' as 'named',
format: 'esm',
sourcemap: sourceMap ?? isOptimized,
exports: 'named',
chunkFileNames: 'common/[name]-[hash].js',
};
if (Object.keys(depObject).length > 0) {
try {
const packageBundle = await rollup.rollup(inputOptions);
const packageBundle = await rollup(inputOptions);
await packageBundle.write(outputOptions);
} catch (err) {
const {loc} = err as rollup.RollupError;
const {loc} = err as RollupError;
if (!loc || !loc.file) {
throw err;
}
Expand All @@ -459,7 +458,7 @@ export async function install(

if (nomodule) {
const nomoduleStart = Date.now();
function rollupResolutionHelper() {
function rollupResolutionHelper(): Plugin {
return {
name: 'rename-import-plugin',
resolveId(source) {
Expand All @@ -470,21 +469,21 @@ export async function install(
// resolve web_modules
if (source.includes('/web_modules/')) {
const suffix = source.split('/web_modules/')[1];
return {id: path.join(destLoc, suffix)};
return {id: path.join(destLoc!, suffix)};
}
// null means try to resolve as-is
return null;
},
};
}
try {
const noModuleBundle = await rollup.rollup({
const noModuleBundle = await rollup({
input: path.resolve(cwd, nomodule),
inlineDynamicImports: true,
plugins: [...inputOptions.plugins, rollupResolutionHelper()],
plugins: [...inputOptions.plugins!, rollupResolutionHelper()],
});
await noModuleBundle.write({
file: path.resolve(destLoc, nomoduleOutput),
file: path.resolve(destLoc!, nomoduleOutput!),
format: 'iife',
name: 'App',
});
Expand All @@ -505,7 +504,7 @@ export async function install(
}
}
fs.writeFileSync(
path.join(destLoc, 'import-map.json'),
path.join(destLoc!, 'import-map.json'),
JSON.stringify({imports: importMap}, undefined, 2),
{encoding: 'utf8'},
);
Expand Down Expand Up @@ -561,7 +560,7 @@ export async function cli(args: string[]) {
fs.existsSync(path.join(cwd, 'browserslist'));

let isExplicit = false;
const installTargets = [];
const installTargets: InstallTarget[] = [];

if (webDependencies) {
isExplicit = true;
Expand Down
30 changes: 17 additions & 13 deletions src/rollup-plugin-dependency-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs';
import path from 'path';
import {OutputOptions, OutputBundle} from 'rollup';
import {OutputBundle, Plugin} from 'rollup';

export type DependencyStats = {
size: number;
Expand All @@ -12,7 +12,9 @@ type DependencyStatsMap = {
type DependencyType = 'direct' | 'common';
export type DependencyStatsOutput = Record<DependencyType, DependencyStatsMap>;

export function rollupPluginDependencyStats(cb: (dependencyInfo: DependencyStatsOutput) => void) {
export function rollupPluginDependencyStats(
cb: (dependencyInfo: DependencyStatsOutput) => void,
): Plugin {
let outputDir: string;
let cache: {[fileName: string]: number} = {};
let output: DependencyStatsOutput = {
Expand Down Expand Up @@ -46,20 +48,22 @@ export function rollupPluginDependencyStats(cb: (dependencyInfo: DependencyStats
}

return {
generateBundle(options: OutputOptions, bundle: OutputBundle) {
outputDir = options.dir;
name: 'pika:rollup-plugin-dependency-info',
generateBundle(options, bundle) {
outputDir = options.dir!;
buildCache(bundle);
},
writeBundle(bundle: OutputBundle) {
const files = Object.keys(bundle);
writeBundle(bundle) {
const directDependencies: string[] = [];
const commonDependencies: string[] = [];

const [directDependencies, commonDependencies] = files.reduce(
([direct, common], fileName) =>
fileName.startsWith('common')
? [direct, [...common, fileName]]
: [[...direct, fileName], common],
[[], []],
);
for (const fileName of Object.keys(bundle)) {
if (fileName.startsWith('common')) {
commonDependencies.push(fileName);
} else {
directDependencies.push(fileName);
}
}

compareDependencies(directDependencies, 'direct');
compareDependencies(commonDependencies, 'common');
Expand Down
9 changes: 5 additions & 4 deletions src/rollup-plugin-entrypoint-alias.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from 'path';
import {Plugin} from 'rollup';
import {resolveDependencyManifest} from './util';

const IS_DEEP_PACKAGE_IMPORT = /^(@[\w-]+\/)?([\w-]+)\/(.*)/;
Expand All @@ -12,14 +13,14 @@ const IS_DEEP_PACKAGE_IMPORT = /^(@[\w-]+\/)?([\w-]+)\/(.*)/;
* Even though both eventually resolve to the same place, without this plugin
* we lose the ability to mark "lit-html" as an external package.
*/
export function rollupPluginEntrypointAlias({cwd}: {cwd: string}) {
export function rollupPluginEntrypointAlias({cwd}: {cwd: string}): Plugin {
return {
name: 'pika:rollup-plugin-entrypoint-alias',
resolveId(source: string, importer) {
resolveId(source, importer) {
if (!IS_DEEP_PACKAGE_IMPORT.test(source)) {
return null;
}
const [, packageScope, packageName] = source.match(IS_DEEP_PACKAGE_IMPORT);
const [, packageScope, packageName] = source.match(IS_DEEP_PACKAGE_IMPORT)!;
const packageFullName = packageScope ? `${packageScope}${packageName}` : packageName;
const [, manifest] = resolveDependencyManifest(packageFullName, cwd);
if (!manifest) {
Expand All @@ -36,7 +37,7 @@ export function rollupPluginEntrypointAlias({cwd}: {cwd: string}) {
return null;
}

return this.resolve(packageFullName, importer, {skipSelf: true}).then(resolved => {
return this.resolve(packageFullName, importer!, {skipSelf: true}).then(resolved => {
return resolved || null;
});
},
Expand Down
8 changes: 5 additions & 3 deletions src/rollup-plugin-remote-resolve.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {Plugin} from 'rollup';

/**
* rollup-plugin-remote-resolve
*
Expand All @@ -10,11 +12,11 @@ export function rollupPluginRemoteResolve({
}: {
remoteUrl: string;
remotePackages: [string, string][];
}) {
}): Plugin {
const remotePackageMap = new Map(remotePackages);
return {
name: 'pika:peer-dependency-resolver',
resolveId(source: string) {
resolveId(source) {
if (remotePackageMap.has(source)) {
let urlSourcePath = source;
// NOTE(@fks): This is really Pika CDN specific, but no one else should be using this option.
Expand All @@ -29,7 +31,7 @@ export function rollupPluginRemoteResolve({
}
return null;
},
load(id) {
load() {
return null;
},
};
Expand Down
Loading