Skip to content
Draft
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
6 changes: 5 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ pnpm run all:build # full production build
pnpm nx build:dev devextreme # single package, dev mode
pnpm nx build devextreme -c=testing # CI testing configuration
pnpm nx build:transpile devextreme # transpile only (babel-transform / build-typescript)
pnpm nx build:transpile:watch devextreme # transpile in watch mode (incremental JS + TS rebuild)
pnpm nx transpile:tests devextreme # transpile testing/**/*.js in place (replaces gulp transpile-tests)
pnpm nx dev devextreme # build:dev, then start all dev watches (replaces gulp dev)
pnpm nx dev-watch devextreme # start all dev watches in parallel, skipping the initial build
pnpm nx bundle:debug devextreme # debug bundle (Webpack via nx-infra-plugin)
pnpm nx bundle:prod devextreme # production bundle
pnpm nx build:localization devextreme # localization files only
Expand Down Expand Up @@ -197,7 +201,7 @@ For the full executor catalogue, conventions, and refactoring guidance, see @pac

## Build Pipeline

clean (`devextreme-nx-infra-plugin:clean` preserving CSS and npm metadata) → localization → component generation (Renovation) → transpile (`babel-transform` for JS, `build-typescript` for TS) → bundle (Webpack via `devextreme-nx-infra-plugin:bundle`, debug + prod targets) → TypeScript declarations → SCSS compile (`devextreme-scss`) → npm package preparation. Task orchestration goes through Nx; cross-package builds (`all:build-dev`, `all:build`) live in the `workflows` package. The `gulpfile.js` clean task is a thin delegate to `pnpm nx clean:artifacts devextreme`. Pre-commit hook runs `lint-staged` (stylelint + eslint --quiet).
clean (`devextreme-nx-infra-plugin:clean` preserving CSS and npm metadata) → localization → component generation (Renovation) → transpile (`babel-transform` for JS, `build-typescript` for TS) → bundle (Webpack via `devextreme-nx-infra-plugin:bundle`, debug + prod targets) → TypeScript declarations → SCSS compile (`devextreme-scss`) → npm package preparation. Task orchestration goes through Nx; cross-package builds (`all:build-dev`, `all:build`) live in the `workflows` package. The `gulpfile.js` clean task is a thin delegate to `pnpm nx clean:artifacts devextreme`. Pre-commit hook runs `lint-staged` (stylelint + eslint --quiet). The developer watch workflow (`pnpm run dev` / `dev:watch`) is now native composite Nx targets (`dev`, `dev-watch`) rather than gulp orchestrators — see the "Migrated gulp tasks" table in @packages/nx-infra-plugin/AGENTS.md.

## Conventions

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@types/node": "catalog:tools",
"@types/shelljs": "0.8.15",
"axe-core": "catalog:",
"chokidar": "5.0.0",
"@types/yargs": "17.0.35",
"devextreme-internal-tools": "catalog:tools",
"devextreme-metadata": "workspace:*",
Expand Down
1 change: 0 additions & 1 deletion packages/devextreme-scss/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"type": "module",
"devDependencies": {
"autoprefixer": "10.5.0",
"chokidar": "5.0.0",
"clean-css": "5.3.3",
"opentype.js": "1.3.4",
"postcss": "8.5.10",
Expand Down
45 changes: 4 additions & 41 deletions packages/devextreme/build/gulp/bundler-config.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,8 @@
'use strict';

const gulp = require('gulp');
const replace = require('gulp-replace');
const concat = require('gulp-concat');
const rename = require('gulp-rename');
const header = require('gulp-header');
const eol = require('gulp-eol');
const shell = require('gulp-shell');

const context = require('./context.js');
const headerPipes = require('./header-pipes.js');
const { packageDir } = require('./utils');

const BUNDLE_CONFIG_SOURCES = [
'build/bundle-templates/modules/parts/core.js',
'build/bundle-templates/modules/parts/data.js',
'build/bundle-templates/modules/parts/widgets-base.js',
'build/bundle-templates/modules/parts/widgets-web.js',
'build/bundle-templates/modules/parts/viz.js',
'build/bundle-templates/modules/parts/aspnet.js'
];

gulp.task('bundler-config', function() {
return gulp.src(BUNDLE_CONFIG_SOURCES)
.pipe(replace(/[^]*BUNDLER_PARTS.*?$([^]*)^.*?BUNDLER_PARTS_END[^]*/gm, '$1'))
.pipe(concat('dx.custom.js'))
.pipe(header('/* Comment lines below for the widgets you don\'t require and run "devextreme-bundler" in this directory, then include dx.custom.js in your project */'))
.pipe(headerPipes.useStrict())
.pipe(replace(/require *\( *["']..\/..\//g, 'require(\''))
.pipe(replace(/^[ ]{4}/gm, ''))
.pipe(replace(/^[\n\r]{2,}/gm, '\n\n'))
.pipe(eol())
.pipe(gulp.dest('build/bundle-templates'))
.pipe(rename('dx.custom.config.js'))
.pipe(replace(/require *\( *["']..\//g, 'require(\'devextreme/'))
.pipe(gulp.dest(`${context.RESULT_NPM_PATH}/${packageDir}/bundles`));
});

gulp.task('bundler-config-watch', function() {
return gulp
.watch(BUNDLE_CONFIG_SOURCES, gulp.series('bundler-config'))
.on('ready', () => console.log(
'bundler-config task is watching for changes...'
));
});
gulp.task('bundler-config', shell.task(
'pnpm nx build:devextreme-bundler-config devextreme && pnpm nx build:devextreme-bundler-config devextreme -c prod'
));
97 changes: 0 additions & 97 deletions packages/devextreme/build/gulp/js-bundles.js

This file was deleted.

44 changes: 1 addition & 43 deletions packages/devextreme/build/gulp/localization.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,8 @@
'use strict';

const gulp = require('gulp');
const path = require('path');
const shell = require('gulp-shell');
const through = require('through2');
const fs = require('fs');

const DEFAULT_LOCALE = 'en';
const DICTIONARY_SOURCE_FOLDER = 'js/localization/messages';

gulp.task('localization', shell.task('pnpm nx build:localization devextreme'));

gulp.task('generate-community-locales', () => {
const defaultFile = fs.readFileSync(path.join(DICTIONARY_SOURCE_FOLDER, DEFAULT_LOCALE + '.json')).toString();
const defaultDictionaryKeys = Object.keys(JSON.parse(defaultFile)[DEFAULT_LOCALE]);

return gulp
.src([
'js/localization/messages/*.json',
'!js/localization/messages/en.json'
])
.pipe(through.obj(function(file, encoding, callback) {
const parsedFile = JSON.parse(file.contents.toString(encoding));

const [locale] = Object.keys(parsedFile);
const dictionary = parsedFile[locale];

let newFile = defaultFile.replace(`"${DEFAULT_LOCALE}"`, `"${locale}"`);

defaultDictionaryKeys.forEach((key) => {
let replaceValue = null;
// eslint-disable-next-line no-prototype-builtins
if(dictionary.hasOwnProperty(key)) {
const val = dictionary[key];
if(!val.includes('TODO')) {
replaceValue = val.replace(/"/g, '\\"');
}
}

if(replaceValue != null) {
newFile = newFile.replace(new RegExp(`"${key}":.*"(,)?`), `"${key}": "${replaceValue}"$1`);
}
});

file.contents = Buffer.from(newFile, encoding);
callback(null, file);
}))
.pipe(gulp.dest(DICTIONARY_SOURCE_FOLDER));
});
gulp.task('generate-community-locales', shell.task('pnpm nx build:community-localization devextreme'));
38 changes: 0 additions & 38 deletions packages/devextreme/build/gulp/systemjs.js

This file was deleted.

82 changes: 2 additions & 80 deletions packages/devextreme/build/gulp/transpile.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,6 @@
'use strict';

const babel = require('gulp-babel');
const gulp = require('gulp');
const notify = require('gulp-notify');
const path = require('path');
const plumber = require('gulp-plumber');
const replace = require('gulp-replace');
const watch = require('gulp-watch');
const shell = require('gulp-shell');

const ctx = require('./context.js');
const testsConfig = require('../../testing/tests.babelrc.json');
const transpileConfig = require('./transpile-config');
const createTsCompiler = require('./typescript/compiler');

const REMOVE_DEBUG_REGEXP = /\/{2,}\s{0,}#DEBUG[\s\S]*?\/{2,}\s{0,}#ENDDEBUG/g;

const src = [
'js/**/*.*',
'!js/**/*.d.ts',
'!js/**/*.{tsx,ts}',
'!js/__internal/**/*.*',
];

const TS_OUTPUT_BASE_DIR = 'artifacts/dist_ts';
const TS_COMPILER_CONFIG = {
baseAbsPath: path.resolve(__dirname, '../..'),
relativePath: {
tsconfig: 'js/__internal/tsconfig.json',
alias: 'js',
dist: TS_OUTPUT_BASE_DIR,
},
tsBaseDirName: '__internal',
messages: {
createDirErr: 'Cannot create directory',
createFileErr: 'Cannot create file',
compilationFailed: 'TS Compilation failed',
},
};

const watchJsTask = () => {
const watchTask = watch(src)
.on('ready', () => console.log('transpile JS is watching for changes...'))
.pipe(plumber({
errorHandler: notify
.onError('Error: <%= error.message %>')
.bind() // bind call is necessary to prevent firing 'end' event in notify.onError implementation
}));
watchTask
.pipe(babel(transpileConfig.cjs))
.pipe(gulp.dest(ctx.TRANSPILED_PATH));
watchTask
.pipe(replace(REMOVE_DEBUG_REGEXP, ''))
.pipe(babel(transpileConfig.cjs))
.pipe(gulp.dest(ctx.TRANSPILED_PROD_RENOVATION_PATH));
return watchTask;
};
watchJsTask.displayName = 'transpile JS watch';

const watchTsTask = async() => {
const compiler = await createTsCompiler(TS_COMPILER_CONFIG);
const tsWatch = compiler.watchTs();

tsWatch
.pipe(plumber({
errorHandler: notify
.onError('Error: <%= error.message %>')
.bind() // bind call is necessary to prevent firing 'end' event in notify.onError implementation
}))
.pipe(babel(transpileConfig.tsCjs))
.pipe(gulp.dest(ctx.TRANSPILED_PATH))
.pipe(replace(REMOVE_DEBUG_REGEXP, ''))
.pipe(gulp.dest(ctx.TRANSPILED_PROD_RENOVATION_PATH));
};
watchTsTask.displayName = 'transpile TS watch';

gulp.task('transpile-watch', gulp.parallel(watchJsTask, watchTsTask));

gulp.task('transpile-tests', gulp.series('bundler-config', () =>
gulp
.src(['testing/**/*.js'])
.pipe(babel(testsConfig))
.pipe(gulp.dest('testing'))
));
gulp.task('transpile-tests', shell.task('pnpm nx transpile:tests devextreme'));
Loading
Loading