Skip to content

Commit

Permalink
Merge pull request #13563 from apache/bundle-dts
Browse files Browse the repository at this point in the history
chore(dts): generate bundled dts distribution
  • Loading branch information
pissang authored Nov 8, 2020
2 parents e860342 + 2086398 commit 904a53c
Show file tree
Hide file tree
Showing 91 changed files with 439 additions and 242 deletions.
171 changes: 105 additions & 66 deletions build/pre-publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const ts = require('typescript');
const globby = require('globby');
const transformDEVUtil = require('./transform-dev');
const preamble = require('./preamble');
// NOTE: v1.4.2 is the latest version that supports ts 3.8.3
const dts = require('rollup-plugin-dts').default;
const rollup = require('rollup');

const ecDir = nodePath.resolve(__dirname, '..');
const tmpDir = nodePath.resolve(ecDir, 'pre-publish-tmp');
Expand Down Expand Up @@ -71,47 +74,6 @@ const typesDir = nodePath.resolve(ecDir, 'types');


const compileWorkList = [
{
logLabel: 'main ts -> js-cjs',
compilerOptionsOverride: {
module: 'CommonJS',
// `rootDir` Only use to control the output
// directory structure with --outDir.
rootDir: ecDir,
outDir: tmpDir
},
srcGlobby: mainSrcGlobby,
transformOptions: {
filesGlobby: {patterns: ['**/*.js'], cwd: tmpDir},
preamble: preamble.js,
transformDEV: true
},
before: async function () {
fsExtra.removeSync(tmpDir);
fsExtra.removeSync(nodePath.resolve(ecDir, 'lib'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.js'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.blank.js'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.common.js'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.simple.js'));
},
after: async function () {
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.all.js'), nodePath.resolve(ecDir, 'index.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.blank.js'), nodePath.resolve(ecDir, 'index.blank.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.common.js'), nodePath.resolve(ecDir, 'index.common.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.simple.js'), nodePath.resolve(ecDir, 'index.simple.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src'), nodePath.resolve(ecDir, 'lib'));

transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.js'), 'lib');
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.blank.js'), 'lib');
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.common.js'), 'lib');
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.simple.js'), 'lib');

await transformDistributionFiles(nodePath.resolve(ecDir, 'lib'), 'lib');
removeESmoduleMark();

fsExtra.removeSync(tmpDir);
}
},
{
logLabel: 'main ts -> js-esm',
compilerOptionsOverride: {
Expand Down Expand Up @@ -150,6 +112,48 @@ const compileWorkList = [

await transformDistributionFiles(nodePath.resolve(ecDir, 'esm'), 'esm');
await transformDistributionFiles(nodePath.resolve(ecDir, 'types'), 'esm');
fsExtra.removeSync(tmpDir);

await bundleDTS();
}
},
{
logLabel: 'main ts -> js-cjs',
compilerOptionsOverride: {
module: 'CommonJS',
// `rootDir` Only use to control the output
// directory structure with --outDir.
rootDir: ecDir,
outDir: tmpDir
},
srcGlobby: mainSrcGlobby,
transformOptions: {
filesGlobby: {patterns: ['**/*.js'], cwd: tmpDir},
preamble: preamble.js,
transformDEV: true
},
before: async function () {
fsExtra.removeSync(tmpDir);
fsExtra.removeSync(nodePath.resolve(ecDir, 'lib'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.js'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.blank.js'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.common.js'));
fsExtra.removeSync(nodePath.resolve(ecDir, 'index.simple.js'));
},
after: async function () {
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.all.js'), nodePath.resolve(ecDir, 'index.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.blank.js'), nodePath.resolve(ecDir, 'index.blank.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.common.js'), nodePath.resolve(ecDir, 'index.common.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src/echarts.simple.js'), nodePath.resolve(ecDir, 'index.simple.js'));
fs.renameSync(nodePath.resolve(tmpDir, 'src'), nodePath.resolve(ecDir, 'lib'));

transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.js'), 'lib');
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.blank.js'), 'lib');
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.common.js'), 'lib');
transformRootFolderInEntry(nodePath.resolve(ecDir, 'index.simple.js'), 'lib');

await transformDistributionFiles(nodePath.resolve(ecDir, 'lib'), 'lib');
removeESmoduleMark();

fsExtra.removeSync(tmpDir);
}
Expand Down Expand Up @@ -230,23 +234,11 @@ module.exports = async function () {
console.log(chalk.green.dim('All done.'));
};

async function tsCompile(compilerOptionsOverride, srcPathList) {
assert(
compilerOptionsOverride
&& compilerOptionsOverride.module
&& compilerOptionsOverride.rootDir
&& compilerOptionsOverride.outDir
);

let compilerOptions = {
...tsConfig.compilerOptions,
...compilerOptionsOverride,
sourceMap: false
};

async function runTsCompile(localTs, compilerOptions, srcPathList) {
// Must do it. becuase the value in tsconfig.json might be different from the inner representation.
// For example: moduleResolution: "NODE" => moduleResolution: 2
const {options, errors} = ts.convertCompilerOptionsFromJson(compilerOptions, ecDir);
const {options, errors} = localTs.convertCompilerOptionsFromJson(compilerOptions, ecDir);

if (errors.length) {
let errMsg = 'tsconfig parse failed: '
+ errors.map(error => error.messageText).join('. ')
Expand All @@ -255,25 +247,44 @@ async function tsCompile(compilerOptionsOverride, srcPathList) {
}

// See: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
let program = ts.createProgram(srcPathList, options);

let program = localTs.createProgram(srcPathList, options);
let emitResult = program.emit();

let allDiagnostics = ts
let allDiagnostics = localTs
.getPreEmitDiagnostics(program)
.concat(emitResult.diagnostics);

allDiagnostics.forEach(diagnostic => {
if (diagnostic.file) {
let {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
let message = localTs.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
console.log(chalk.red(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`));
}
else {
console.log(chalk.red(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')));
console.log(chalk.red(localTs.flattenDiagnosticMessageText(diagnostic.messageText, '\n')));
}
});
assert(!emitResult.emitSkipped, 'ts compile failed.');
}
module.exports.runTsCompile = runTsCompile;

async function tsCompile(compilerOptionsOverride, srcPathList) {
assert(
compilerOptionsOverride
&& compilerOptionsOverride.module
&& compilerOptionsOverride.rootDir
&& compilerOptionsOverride.outDir
);

let compilerOptions = {
...tsConfig.compilerOptions,
...compilerOptionsOverride,
sourceMap: false
};

runTsCompile(ts, compilerOptions, srcPathList);
}

/**
* Transform import/require path in the entry file to `esm` or `lib`.
Expand Down Expand Up @@ -311,9 +322,9 @@ async function transformDistributionFiles(rooltFolder, replacement) {
code = singleTransformZRRootFolder(code, replacement);
// For lower ts version, not use import type
// TODO Use https://github.com/sandersn/downlevel-dts ?
if (fileName.endsWith('.d.ts')) {
code = singleTransformImportType(code);
}
// if (fileName.endsWith('.d.ts')) {
// code = singleTransformImportType(code);
// }
fs.writeFileSync(fileName, code, 'utf-8');
}
}
Expand Down Expand Up @@ -342,9 +353,9 @@ function singleTransformZRRootFolder(code, replacement) {
return code.replace(/([\"\'])zrender\/src\//g, `$1zrender/${replacement}/`);
}

function singleTransformImportType(code) {
return code.replace(/import\s+type\s+/g, 'import ');
}
// function singleTransformImportType(code) {
// return code.replace(/import\s+type\s+/g, 'import ');
// }

/**
* @param {Object} transformOptions
Expand Down Expand Up @@ -383,10 +394,38 @@ async function readFilePaths({patterns, cwd}) {
);
}

async function bundleDTS() {
const bundle = await rollup.rollup({
input: nodePath.resolve(__dirname, '../index.d.ts'),
onwarn(warning, rollupWarn) {
// Not warn circular dependency
if (warning.code !== 'CIRCULAR_DEPENDENCY') {
rollupWarn(warning);
}
},
plugins: [
dts({
respectExternal: true
})
]
});
const bundleFile = nodePath.resolve(__dirname, '../types/dist/echarts.d.ts');
await bundle.write({
file: bundleFile
});
// To support ts 3.4
const extra = `
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
`
const code = extra + fs.readFileSync(bundleFile, 'utf-8');
fs.writeFileSync(bundleFile, code, 'utf-8');
}

function readTSConfig() {
// tsconfig.json may have comment string, which is invalid if
// using `require('tsconfig.json'). So we use a loose parser.
let filePath = nodePath.resolve(ecDir, 'tsconfig.json');
const tsConfigText = fs.readFileSync(filePath, {encoding: 'utf8'});
return (new Function(`return ( ${tsConfigText} )`))();
}
module.exports.readTSConfig = readTSConfig;
54 changes: 54 additions & 0 deletions build/testDts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const { TypeScriptVersion } = require('@definitelytyped/typescript-versions');
const {
cleanTypeScriptInstalls,
installAllTypeScriptVersions,
typeScriptPath
} = require('@definitelytyped/utils');
const { runTsCompile, readTSConfig } = require('./pre-publish');
const globby = require('globby');
const semver = require('semver');

const MIN_VERSION = '3.4.0';

async function installTs() {
// await cleanTypeScriptInstalls();
await installAllTypeScriptVersions();
}

async function runTests() {
const tsConfig = readTSConfig();
const compilerOptions = {
...tsConfig.compilerOptions,
declaration: false,
importHelpers: false,
sourceMap: false,
pretty: false,
removeComments: false,
allowJs: false,
outDir: __dirname + '/../test/types/tmp',
typeRoots: [__dirname + '/../types/dist'],
rootDir: __dirname + '/../test/types'
};
const testsList = await globby(__dirname + '/../test/types/*.ts');

for (let version of TypeScriptVersion.shipped) {
if (semver.lt(version + '.0', MIN_VERSION)) {
continue;
}

console.log(`Testing ts version ${version}`);
const ts = require(typeScriptPath(version));
await runTsCompile(ts, compilerOptions, testsList);

console.log(`Finished test of ts version ${version}`);
}
}

async function main() {
await installTs();
await runTests();
}

module.exports = main;

main();
7 changes: 6 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
/// Make sure run it before edit this file. ///
///////////////////////////////////////////////////////////////////////

export * from './types/src/echarts.all';

// Restrict exports
export {
init, connect, disConnect, dispose, getInstanceByDom, getInstanceById,
registerMap, registerLocale, getMap, registerTheme
} from './types/src/echarts.all';

export {EChartsFullOption as EChartsOption} from './types/src/option';
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"main": "index.js",
"module": "echarts.all.js",
"jsdelivr": "dist/echarts.min.js",
"types": "index.d.ts",
"types": "types/dist/echarts.d.ts",
"homepage": "http://echarts.apache.org",
"repository": {
"type": "git",
Expand All @@ -29,6 +29,7 @@
"test:visual:report": "node test/runTest/genReport.js",
"test": "jest --config test/ut/jest.config.js",
"test:single": "jest --config test/ut/jest.config.js --coverage=false -t",
"test:dts": "node build/testDts.js",
"mktest": "node test/build/mktest.js",
"mktest:help": "node test/build/mktest.js -h",
"lint": "./node_modules/.bin/eslint src/**/*.ts extension-src/**/*.ts",
Expand All @@ -49,6 +50,7 @@
"chalk": "^3.0.0",
"chokidar": "^3.4.0",
"commander": "2.11.0",
"dtslint": "^4.0.5",
"esbuild": "^0.4.1",
"eslint": "6.3.0",
"fs-extra": "0.26.7",
Expand All @@ -64,6 +66,7 @@
"pngjs": "3.4.0",
"rollup": "1.28.0",
"rollup-plugin-commonjs": "8.4.1",
"rollup-plugin-dts": "1.4.2",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-typescript2": "0.25.3",
"seedrandom": "3.0.3",
Expand Down
14 changes: 11 additions & 3 deletions src/ExtensionAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import {EChartsType} from './echarts';
import {CoordinateSystemMaster} from './coord/CoordinateSystem';
import Element from 'zrender/src/Element';
import ComponentModel from './model/Component';
import ComponentView from './view/Component';
import ChartView from './view/Chart';
import SeriesModel from './model/Series';
import GlobalModel from './model/Global';

const availableMethods: (keyof EChartsType)[] = [
'getDom',
Expand All @@ -35,10 +39,10 @@ const availableMethods: (keyof EChartsType)[] = [
'off',
'getDataURL',
'getConnectedDataURL',
'getModel',
// 'getModel',
'getOption',
'getViewOfComponentModel',
'getViewOfSeriesModel',
// 'getViewOfComponentModel',
// 'getViewOfSeriesModel',
'getId',
'updateLabelLayout'
];
Expand All @@ -62,6 +66,10 @@ abstract class ExtensionAPI {
abstract leaveSelect(el: Element): void;
abstract enterBlur(el: Element): void;
abstract leaveBlur(el: Element): void;
// These methods are not planned to be exposed to outside.
abstract getViewOfComponentModel(componentModel: ComponentModel): ComponentView;
abstract getViewOfSeriesModel(seriesModel: SeriesModel): ChartView;
abstract getModel(): GlobalModel;
}

export default ExtensionAPI;
Loading

0 comments on commit 904a53c

Please sign in to comment.