@itee/tasks 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/tasks.iml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/CHANGELOG.md +56 -0
  6. package/README.md +1 -0
  7. package/configs/builds/build.conf.mjs +1 -0
  8. package/configs/cleans/clean.conf.mjs +1 -0
  9. package/configs/docs/doc.conf.json +1 -0
  10. package/configs/lints/lint.conf.mjs +91 -0
  11. package/configs/refresh.conf.mjs +1 -0
  12. package/configs/tests/benchmarks/compute-benchmarks.conf.mjs +5 -0
  13. package/configs/tests/benchmarks/run-benchmarks-for-frontend.conf.mjs +37 -0
  14. package/configs/tests/benchmarks/run-benchmarks.conf.mjs +7 -0
  15. package/configs/tests/bundlings/check-bundling-from-esm-build-import.conf.mjs +45 -0
  16. package/configs/tests/bundlings/check-bundling-from-esm-files-direct.conf.mjs +51 -0
  17. package/configs/tests/bundlings/check-bundling-from-esm-files-import.conf.mjs +48 -0
  18. package/configs/tests/units/compute-unit-tests.conf.mjs +5 -0
  19. package/configs/tests/units/run-unit-tests-for-frontend.conf.mjs +14 -0
  20. package/configs/tests/units/run-unit-tests.conf.mjs +7 -0
  21. package/package.json +100 -0
  22. package/sources/_utils.mjs +412 -0
  23. package/sources/builds/build.task.mjs +52 -0
  24. package/sources/cleans/clean.task.mjs +32 -0
  25. package/sources/docs/doc.task.mjs +48 -0
  26. package/sources/helps/help.task.mjs +155 -0
  27. package/sources/index.mjs +21 -0
  28. package/sources/lints/lint.task.mjs +46 -0
  29. package/sources/refresh.mjs +100 -0
  30. package/sources/releases/release.task.mjs +32 -0
  31. package/sources/tests/benchmarks/compute-benchmarks.task.mjs +236 -0
  32. package/sources/tests/benchmarks/run-benchmarks-for-backend.task.mjs +43 -0
  33. package/sources/tests/benchmarks/run-benchmarks-for-frontend.task.mjs +48 -0
  34. package/sources/tests/benchmarks/run-benchmarks.task.mjs +16 -0
  35. package/sources/tests/bundlings/check-bundling-from-esm-build-import.task.mjs +127 -0
  36. package/sources/tests/bundlings/check-bundling-from-esm-files-direct.task.mjs +94 -0
  37. package/sources/tests/bundlings/check-bundling-from-esm-files-import.task.mjs +113 -0
  38. package/sources/tests/bundlings/check-bundling.task.mjs +24 -0
  39. package/sources/tests/run-tests.task.mjs +22 -0
  40. package/sources/tests/units/compute-unit-tests.task.mjs +547 -0
  41. package/sources/tests/units/run-unit-tests-for-backend.task.mjs +48 -0
  42. package/sources/tests/units/run-unit-tests-for-frontend.task.mjs +48 -0
  43. package/sources/tests/units/run-unit-tests.task.mjs +16 -0
@@ -0,0 +1,21 @@
1
+ export { buildTask } from './builds/build.task.mjs'
2
+ export { cleanTask } from './cleans/clean.task.mjs'
3
+ export { docTask } from './docs/doc.task.mjs'
4
+ export { helpTask } from './helps/help.task.mjs'
5
+ export { lintTask } from './lints/lint.task.mjs'
6
+ export { releaseTask } from './releases/release.task.mjs'
7
+ export { runTestsTask } from './tests/run-tests.task.mjs'
8
+ export { computeUnitTestsTask } from './tests/units/compute-unit-tests.task.mjs'
9
+ export { runUnitTestsTask } from './tests/units/run-unit-tests.task.mjs'
10
+ export { runUnitTestsForBackendTask } from './tests/units/run-unit-tests-for-backend.task.mjs'
11
+ export { runUnitTestsForFrontendTask } from './tests/units/run-unit-tests-for-frontend.task.mjs'
12
+ export { checkBundlingFromEsmBuildImportTask } from './tests/bundlings/check-bundling-from-esm-build-import.task.mjs'
13
+ export { checkBundlingFromEsmFilesDirectTask } from './tests/bundlings/check-bundling-from-esm-files-direct.task.mjs'
14
+ export { checkBundlingFromEsmFilesImportTask } from './tests/bundlings/check-bundling-from-esm-files-import.task.mjs'
15
+ export { checkBundlingTask } from './tests/bundlings/check-bundling.task.mjs'
16
+ export { computeBenchmarksTask } from './tests/benchmarks/compute-benchmarks.task.mjs'
17
+ export { runBenchmarksTestsTask } from './tests/benchmarks/run-benchmarks.task.mjs'
18
+ export { runBenchmarksForBackendTask } from './tests/benchmarks/run-benchmarks-for-backend.task.mjs'
19
+ export { runBenchmarksForFrontendTask } from './tests/benchmarks/run-benchmarks-for-frontend.task.mjs'
20
+
21
+ export * from './_utils.mjs'
@@ -0,0 +1,46 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import child_process from 'node:child_process'
4
+ import { basename } from 'node:path'
5
+ import { promisify } from 'node:util'
6
+ import {
7
+ getTaskConfigurationPathFor,
8
+ logLoadingTask
9
+ } from '../_utils.mjs'
10
+
11
+ logLoadingTask( import.meta.filename )
12
+
13
+ const execFile = promisify( child_process.execFile )
14
+ const { red } = colors
15
+
16
+ /**
17
+ * @method npm run lint
18
+ * @global
19
+ * @description Will lint the sources files and try to fix the style when possible
20
+ */
21
+ const lintTask = async ( done ) => {
22
+
23
+ try {
24
+
25
+ const configurationPath = getTaskConfigurationPathFor( import.meta.filename )
26
+
27
+ const { stdout } = await execFile( 'npx', [ 'eslint', '--config', configurationPath, '--fix' ] )
28
+ if ( stdout !== '' ) {
29
+ log( stdout )
30
+ }
31
+
32
+ done()
33
+
34
+ } catch ( error ) {
35
+
36
+ log( error.stdout )
37
+ done( red( error.message ) )
38
+
39
+ }
40
+
41
+ }
42
+ lintTask.displayName = basename( import.meta.filename, '.task.mjs' )
43
+ lintTask.description = 'Will lint the sources files and try to fix the style when possible.'
44
+ lintTask.flags = null
45
+
46
+ export { lintTask }
@@ -0,0 +1,100 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import { writeFileSync } from 'fs'
4
+ import {
5
+ basename,
6
+ join,
7
+ relative
8
+ } from 'path'
9
+ import {
10
+ getFilesFrom,
11
+ getTaskConfigurationFor,
12
+ iteePackageRootDirectory,
13
+ iteePackageSourcesDirectory,
14
+ packageNodeModulesDirectory,
15
+ packageRootDirectory,
16
+ packageTasksDirectory
17
+ } from './_utils.mjs'
18
+
19
+ const {
20
+ green,
21
+ yellow
22
+ } = colors
23
+
24
+ const configuration = await getTaskConfigurationFor( import.meta.filename )
25
+
26
+ // Get and filter tasks to expose
27
+ const defaultTaskPattern = join( iteePackageSourcesDirectory, '/{*.task.mjs,**/*.task.mjs,**/**/*.task.mjs}' )
28
+ const defaultTaskFiles = getFilesFrom(
29
+ defaultTaskPattern,
30
+ filePath => {
31
+ const relativeFilepath = relative( iteePackageSourcesDirectory, filePath )
32
+ const filename = basename( filePath )
33
+ const included = !configuration.includes( filename )
34
+
35
+ included
36
+ ? log( 'Include default task from', green( relativeFilepath ) )
37
+ : log( 'Exclude default task from', yellow( relativeFilepath ) )
38
+
39
+ return included
40
+ }
41
+ )
42
+
43
+ const userTaskPattern = join( packageTasksDirectory, '/{*.task.mjs,**/*.task.mjs,**/**/*.task.mjs}' )
44
+ const userTaskFiles = getFilesFrom(
45
+ userTaskPattern,
46
+ filePath => {
47
+ const relativeFilepath = relative( packageRootDirectory, filePath )
48
+ const filename = basename( filePath )
49
+ const included = !configuration.includes( filename )
50
+
51
+ included
52
+ ? log( 'Include user task from', green( relativeFilepath ) )
53
+ : log( 'Exclude user task from', yellow( relativeFilepath ) )
54
+
55
+ return included
56
+ }
57
+ )
58
+
59
+ // Prepare gulpfile content with header
60
+ let gulpfileContent = '' +
61
+ '/**\n' +
62
+ ' * This file is auto-generated by internal gulp command.\n' +
63
+ ' * If you want to customize the available gulp tasks, create your own in .tasks folder\n' +
64
+ ' * and run "gulp refresh"\n' +
65
+ ' */\n\n'
66
+
67
+ // Generate default tasks exports and append to gulpfile content
68
+ gulpfileContent += '// Default Itee tasks\n'
69
+ for ( const taskFile of defaultTaskFiles ) {
70
+
71
+ // we are calling from client and use relative path from it
72
+ if ( iteePackageRootDirectory.includes( 'node_modules' ) ) {
73
+
74
+ const relativeTaskFile = relative( packageNodeModulesDirectory, taskFile )
75
+ gulpfileContent += `export * from '${ relativeTaskFile }'\n`
76
+
77
+ } else { // we are refreshing itee-tasks package internally
78
+
79
+ const relativeTaskFile = relative( iteePackageRootDirectory, taskFile )
80
+ gulpfileContent += `export * from './${ relativeTaskFile }'\n`
81
+
82
+ }
83
+
84
+ }
85
+
86
+ gulpfileContent += '\n'
87
+
88
+ // Generate user tasks exports and append to gulpfile content
89
+ if ( userTaskFiles.length > 0 ) {
90
+ gulpfileContent += '// User defined tasks\n'
91
+ }
92
+ for ( const taskFile of userTaskFiles ) {
93
+ const relativeTaskFile = relative( packageRootDirectory, taskFile )
94
+ gulpfileContent += `export * from './${ relativeTaskFile }'\n`
95
+ }
96
+
97
+ // Create gulpfile file
98
+ const gulpfilePath = join( packageRootDirectory, 'gulpfile.mjs' )
99
+ log( 'Refresh', green( gulpfilePath ) )
100
+ writeFileSync( gulpfilePath, gulpfileContent )
@@ -0,0 +1,32 @@
1
+ import { series } from 'gulp'
2
+ import { basename } from 'node:path'
3
+ import { logLoadingTask } from '../_utils.mjs'
4
+ import { buildTask } from '../builds/build.task.mjs'
5
+ import { cleanTask } from '../cleans/clean.task.mjs'
6
+ import { docTask } from '../docs/doc.task.mjs'
7
+ import { lintTask } from '../lints/lint.task.mjs'
8
+ import { computeBenchmarksTask } from '../tests/benchmarks/compute-benchmarks.task.mjs'
9
+ import { runTestsTask } from '../tests/run-tests.task.mjs'
10
+ import { computeUnitTestsTask } from '../tests/units/compute-unit-tests.task.mjs'
11
+
12
+ logLoadingTask( import.meta.filename )
13
+
14
+ /**
15
+ * @method npm run release
16
+ * @global
17
+ * @description Will perform a complete release of the library including 'clean', 'lint', 'doc', 'build-tests', 'test' and finally 'build'.
18
+ */
19
+ const releaseTask = series(
20
+ cleanTask,
21
+ buildTask,
22
+ computeBenchmarksTask,
23
+ computeUnitTestsTask,
24
+ runTestsTask,
25
+ lintTask,
26
+ docTask,
27
+ )
28
+ releaseTask.displayName = basename( import.meta.filename, '.task.mjs' )
29
+ releaseTask.description = 'Will perform a complete release of the library including \'clean\', \'lint\', \'doc\', \'test\' and finally \'build\'.'
30
+ releaseTask.flags = null
31
+
32
+ export { releaseTask }
@@ -0,0 +1,236 @@
1
+ import colors from 'ansi-colors'
2
+ import childProcess from 'child_process'
3
+ import log from 'fancy-log'
4
+ import { glob } from 'glob'
5
+ import {
6
+ basename,
7
+ dirname,
8
+ extname,
9
+ join,
10
+ normalize,
11
+ relative
12
+ } from 'path'
13
+ import {
14
+ createDirectoryIfNotExist,
15
+ createFile,
16
+ getTaskConfigurationFor,
17
+ logLoadingTask,
18
+ packageName,
19
+ packageNodeModulesDirectory,
20
+ packageSourcesDirectory,
21
+ packageTestsBenchmarksDirectory,
22
+ packageTestsDirectory
23
+ } from '../../_utils.mjs'
24
+
25
+ logLoadingTask( import.meta.filename )
26
+
27
+ const {
28
+ red,
29
+ yellow,
30
+ } = colors
31
+
32
+ /**
33
+ * @description Will generate benchmarks files from source code against provided alternatives
34
+ */
35
+ const computeBenchmarksTask = async ( done ) => {
36
+
37
+ createDirectoryIfNotExist( packageTestsBenchmarksDirectory )
38
+
39
+ // Get task configuration
40
+ const filePathsToIgnore = await getTaskConfigurationFor( import.meta.filename )
41
+
42
+ // Get source files to process
43
+ const pattern = join( packageSourcesDirectory, '**' )
44
+ const sourceFiles = glob.sync( pattern )
45
+ .map( filePath => normalize( filePath ) )
46
+ .filter( filePath => {
47
+ const fileName = basename( filePath )
48
+ const isJsFile = fileName.endsWith( '.js' )
49
+ const isNotPrivateFile = !fileName.startsWith( '_' )
50
+ const isNotIgnoredFile = !filePathsToIgnore.includes( fileName )
51
+ return isJsFile && isNotPrivateFile && isNotIgnoredFile
52
+ } )
53
+
54
+ const benchRootImports = []
55
+ for ( let sourceFile of sourceFiles ) {
56
+
57
+ const specificFilePath = sourceFile.replace( packageSourcesDirectory, '' )
58
+ const specificDir = dirname( specificFilePath )
59
+
60
+ const fileName = basename( sourceFile, extname( sourceFile ) )
61
+ const benchFileName = `${ fileName }.bench.js`
62
+ const benchDirPath = join( packageTestsBenchmarksDirectory, specificDir )
63
+ const benchFilePath = join( benchDirPath, benchFileName )
64
+
65
+ const nsName = `${ fileName }Namespace`
66
+ const importDirPath = relative( benchDirPath, packageSourcesDirectory )
67
+ const importFilePath = join( importDirPath, specificFilePath ).replace( /\\/g, '/' )
68
+
69
+ try {
70
+
71
+ const jsdocPath = join( packageNodeModulesDirectory, '/jsdoc/jsdoc.js' )
72
+ const jsdocOutput = childProcess.execFileSync( 'node', [ jsdocPath, '-X', sourceFile ] ).toString()
73
+
74
+ const classNames = []
75
+ const usedLongnames = []
76
+ const jsonData = JSON.parse( jsdocOutput ).filter( data => {
77
+
78
+ const longName = data.longname
79
+
80
+ const kind = data.kind
81
+ if ( kind !== 'function' ) {
82
+ if ( kind === 'class' && !classNames.includes( longName ) ) {
83
+ classNames.push( longName )
84
+ }
85
+ return false
86
+ }
87
+
88
+ // We don't care that data bloc have comment they are unused to generate benchmarks
89
+ // const undocumented = data.undocumented
90
+ // if ( undocumented ) {
91
+ // return false
92
+ // }
93
+
94
+ const scope = data.scope
95
+ if ( ![ 'global', 'static' ].includes( scope ) ) {
96
+ return false
97
+ }
98
+
99
+ if ( longName.includes( ' ' ) || longName.includes( '~' ) || usedLongnames.includes( longName ) ) {
100
+ return false
101
+ }
102
+
103
+ for ( let className of classNames ) {
104
+ if ( longName.includes( className ) ) {
105
+ return false
106
+ }
107
+ }
108
+
109
+ usedLongnames.push( longName )
110
+
111
+ return true
112
+
113
+ } )
114
+
115
+ if ( jsonData.length === 0 ) {
116
+ log( 'Ignoring', yellow( `${ sourceFile }, no usable exports found` ) )
117
+ continue
118
+ }
119
+
120
+ // Compute benchmark suites by grouping logically function by name[_x]
121
+ const suiteGroups = {}
122
+ for ( let docData of jsonData ) {
123
+
124
+ try {
125
+
126
+ const functionName = docData.name
127
+ const nameSplits = functionName.split( '_' )
128
+ const rootName = nameSplits[ 0 ]
129
+
130
+ if ( !( rootName in suiteGroups ) ) {
131
+ suiteGroups[ rootName ] = []
132
+ }
133
+
134
+ suiteGroups[ rootName ].push( functionName )
135
+
136
+ } catch ( error ) {
137
+
138
+ log( red( error.message ) )
139
+
140
+ }
141
+
142
+ }
143
+
144
+ // Generate suites
145
+ let benchSuites = ''
146
+ const suitesToExports = []
147
+ for ( let suiteGroupName in suiteGroups ) {
148
+ suitesToExports.push( `${ suiteGroupName }Suite` )
149
+ benchSuites += `const ${ suiteGroupName }Suite = Benchmark.Suite( '${ nsName }.${ suiteGroupName }', Testing.createSuiteOptions() )` + '\n'
150
+
151
+ for ( let suiteGroupValue of suiteGroups[ suiteGroupName ] ) {
152
+ benchSuites += ` .add( '${ suiteGroupValue }()', Testing.iterateOverDataMap( ${ nsName }.${ suiteGroupValue } ), Testing.createBenchmarkOptions() )` + '\n'
153
+ }
154
+
155
+ benchSuites += '\n'
156
+ }
157
+
158
+ // compute relative level to get import wrappers
159
+ const wrapperDirPath = relative( benchDirPath, packageTestsDirectory )
160
+ const importBenchmarkFilePath = join( wrapperDirPath, 'import.benchmarks.js' )
161
+ const importTestingFilePath = join( wrapperDirPath, 'import.testing.js' )
162
+
163
+ const template = '' +
164
+ `import * as ${ nsName } from '${ importFilePath }'` + '\n' +
165
+ `import { getBenchmarkPackage } from '${ importBenchmarkFilePath }'` + '\n' +
166
+ `import { getTestingPackage } from '${ importTestingFilePath }'` + '\n' +
167
+ '\n' +
168
+ `const Benchmark = await getBenchmarkPackage()` + '\n' +
169
+ `const Testing = await getTestingPackage()` + '\n' +
170
+ '\n' +
171
+ `${ benchSuites }` +
172
+ // '\n' +
173
+ `export { ${ suitesToExports } }` + '\n' +
174
+ '\n'
175
+
176
+ const importBenchFilePath = relative( packageTestsBenchmarksDirectory, benchFilePath ).replace( /\\/g, '/' )
177
+ benchRootImports.push( {
178
+ path: importBenchFilePath,
179
+ exports: suitesToExports
180
+ } )
181
+
182
+ createDirectoryIfNotExist( benchDirPath )
183
+ createFile( benchFilePath, template )
184
+
185
+ } catch ( error ) {
186
+
187
+ log( red( error.message ) )
188
+
189
+ }
190
+
191
+ }
192
+
193
+ let templateImports = ''
194
+ let suites = []
195
+ for ( let i = 0 ; i < benchRootImports.length ; i++ ) {
196
+
197
+ const currentBench = benchRootImports[ i ]
198
+ const namedExports = currentBench.exports
199
+ const imports = namedExports.join( ', ' )
200
+ suites.push( ...namedExports )
201
+
202
+ templateImports += `import {${ imports }} from './${ currentBench.path }'` + '\n'
203
+
204
+ }
205
+
206
+ // Use a fallback in case no benches were found at all
207
+ if ( benchRootImports.length === 0 ) {
208
+ log( 'Warning ', yellow( 'No usable exports found, generate default file to avoid frontend breakage.' ) )
209
+ const defaultBenchesDir = join( packageTestsBenchmarksDirectory, 'default' )
210
+ const defaultBenchesPath = join( defaultBenchesDir, 'default.bench.js' )
211
+
212
+ createDirectoryIfNotExist( defaultBenchesDir )
213
+ createFile( defaultBenchesPath, '// Avoid web test runner crash on empty benches' )
214
+ }
215
+
216
+ const benchesTemplate = '' +
217
+ `${ templateImports }` + '\n' +
218
+ 'const suites = [' + '\n' +
219
+ `${ suites.map( suite => `\t${ suite }` ).join( ',\n' ) }` + '\n' +
220
+ ']' + '\n' +
221
+ '\n' +
222
+ `for ( const suite of suites ) {` + '\n' +
223
+ `\tsuite.run()` + '\n' +
224
+ `}` + '\n'
225
+
226
+ const benchesFilePath = join( packageTestsBenchmarksDirectory, `${ packageName }.benchmarks.js` )
227
+ createFile( benchesFilePath, benchesTemplate )
228
+
229
+ done()
230
+
231
+ }
232
+ computeBenchmarksTask.displayName = basename( import.meta.filename, '.task.mjs' )
233
+ computeBenchmarksTask.description = 'Will generate benchmarks files from source code against provided alternatives.'
234
+ computeBenchmarksTask.flags = null
235
+
236
+ export { computeBenchmarksTask }
@@ -0,0 +1,43 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import { existsSync } from 'fs'
4
+ import { basename } from 'node:path'
5
+ import { join } from 'path'
6
+ import {
7
+ logLoadingTask,
8
+ packageName,
9
+ packageTestsBenchmarksDirectory
10
+ } from '../../_utils.mjs'
11
+
12
+ logLoadingTask( import.meta.filename )
13
+
14
+ const {
15
+ red,
16
+ yellow
17
+ } = colors
18
+
19
+ /**
20
+ * @description Will run benchmarks with node
21
+ */
22
+ const runBenchmarksForBackendTask = async ( done ) => {
23
+
24
+ const benchesPath = join( packageTestsBenchmarksDirectory, `/${ packageName }.benchmarks.js` )
25
+ if ( !existsSync( benchesPath ) ) {
26
+ log( yellow( `${ benchesPath } does not exist, skip backend benchmarks...` ) )
27
+ done()
28
+ return
29
+ }
30
+
31
+ try {
32
+ await import(benchesPath)
33
+ done()
34
+ } catch ( error ) {
35
+ done( red( error ) )
36
+ }
37
+
38
+ }
39
+ runBenchmarksForBackendTask.displayName = basename( import.meta.filename, '.task.mjs' )
40
+ runBenchmarksForBackendTask.description = 'Will run benchmarks with node'
41
+ runBenchmarksForBackendTask.flags = null
42
+
43
+ export { runBenchmarksForBackendTask }
@@ -0,0 +1,48 @@
1
+ import { startTestRunner } from '@web/test-runner'
2
+ import colors from 'ansi-colors'
3
+ import { basename } from 'node:path'
4
+ import {
5
+ getTaskConfigurationFor,
6
+ logLoadingTask
7
+ } from '../../_utils.mjs'
8
+
9
+ logLoadingTask( import.meta.filename )
10
+
11
+ const { red } = colors
12
+
13
+ /**
14
+ * @description Will run benchmarks with web-test-runner
15
+ */
16
+ const runBenchmarksForFrontendTask = () => {
17
+ return new Promise( async ( resolve, reject ) => {
18
+
19
+ const configuration = await getTaskConfigurationFor( import.meta.filename )
20
+ const testRunner = await startTestRunner( {
21
+ config: configuration,
22
+ readCliArgs: false,
23
+ readFileConfig: false,
24
+ autoExitProcess: false,
25
+ } )
26
+
27
+ if ( !testRunner ) {
28
+ reject( red( 'Internal test runner error.' ) )
29
+ return
30
+ }
31
+
32
+ // To ensure that testRunner exit event won't be used by other instance of test runner,
33
+ // we need to be sure that current test runner is ended
34
+ testRunner.on( 'finished', () => {
35
+ testRunner.stop()
36
+ } )
37
+
38
+ testRunner.on( 'stopped', () => {
39
+ resolve()
40
+ } )
41
+
42
+ } )
43
+ }
44
+ runBenchmarksForFrontendTask.displayName = basename( import.meta.filename, '.task.mjs' )
45
+ runBenchmarksForFrontendTask.description = 'Will run benchmarks with web-test-runner.'
46
+ runBenchmarksForFrontendTask.flags = null
47
+
48
+ export { runBenchmarksForFrontendTask }
@@ -0,0 +1,16 @@
1
+ import { basename } from 'node:path'
2
+ import {
3
+ getTaskConfigurationFor,
4
+ logLoadingTask,
5
+ serializeTasksFrom
6
+ } from '../../_utils.mjs'
7
+
8
+ logLoadingTask( import.meta.filename )
9
+
10
+ const configuration = await getTaskConfigurationFor( import.meta.filename )
11
+ const runBenchmarksTestsTask = await serializeTasksFrom( configuration )
12
+ runBenchmarksTestsTask.displayName = basename( import.meta.filename, '.task.mjs' )
13
+ runBenchmarksTestsTask.description = 'Will run benchmarks in back and front environments.'
14
+ runBenchmarksTestsTask.flags = null
15
+
16
+ export { runBenchmarksTestsTask }
@@ -0,0 +1,127 @@
1
+ import colors from 'ansi-colors'
2
+ import log from 'fancy-log'
3
+ import {
4
+ existsSync,
5
+ mkdirSync,
6
+ readFileSync,
7
+ rmSync,
8
+ writeFileSync
9
+ } from 'fs'
10
+ import {
11
+ basename,
12
+ join,
13
+ relative
14
+ } from 'path'
15
+ import { rollup } from 'rollup'
16
+ import {
17
+ getTaskConfigurationFor,
18
+ logLoadingTask,
19
+ packageBuildsDirectory,
20
+ packageName,
21
+ packageTestsBundlesDirectory
22
+ } from '../../_utils.mjs'
23
+
24
+ logLoadingTask( import.meta.filename )
25
+
26
+ const {
27
+ red,
28
+ green,
29
+ magenta,
30
+ } = colors
31
+
32
+ const checkBundlingFromEsmBuildImportTask = async ( done ) => {
33
+
34
+ const configuration = await getTaskConfigurationFor( import.meta.filename )
35
+
36
+ const buildFilePath = join( packageBuildsDirectory, `${ packageName }.esm.js` )
37
+ if ( !existsSync( buildFilePath ) ) {
38
+ done( red( buildFilePath + ' does not exist' ) )
39
+ }
40
+
41
+ const outputDir = join( packageTestsBundlesDirectory, 'from_build_import' )
42
+ const temporaryDir = join( packageTestsBundlesDirectory, 'from_build_import', '.tmp' )
43
+ const importDir = relative( temporaryDir, packageBuildsDirectory )
44
+ const importFilePath = join( importDir, `${ packageName }.esm.js` )
45
+
46
+ if ( existsSync( outputDir ) ) {
47
+ log( 'Clean up', magenta( outputDir ) )
48
+ rmSync( outputDir, { recursive: true } )
49
+ }
50
+
51
+ try {
52
+
53
+ // Get build exports list
54
+ const data = readFileSync( buildFilePath, 'utf8' )
55
+ const regex = /export\s{\s(.*)\s}/
56
+ const found = data.match( regex )
57
+ if ( found === null ) {
58
+ log( red( `Unable to find exports in ${ buildFilePath }` ) )
59
+ return
60
+ }
61
+
62
+ const exports = found[ 1 ].split( ',' )
63
+ .map( item => item.trim() )
64
+
65
+ // Create temporary imports files for each build export
66
+ // And then bundle it
67
+ let temporaryFilePaths = []
68
+ for ( let namedExport of exports ) {
69
+ if ( namedExport.includes( ' as ' ) ) {
70
+ namedExport = namedExport.split( ' as ' )[ 1 ]
71
+ }
72
+
73
+ const temporaryFileName = `${ namedExport }.import.js`
74
+ const temporaryFilePath = join( temporaryDir, temporaryFileName )
75
+ const temporaryFileData = `import { ${ namedExport } } from '${ importFilePath.replace( /\\/g, '/' ) }'`
76
+
77
+ mkdirSync( temporaryDir, { recursive: true } )
78
+ writeFileSync( temporaryFilePath, temporaryFileData )
79
+
80
+ temporaryFilePaths.push( temporaryFilePath )
81
+ }
82
+
83
+ // Bundle each temporary files and check side effects
84
+ let fileName, bundleFileName, bundleFilePath
85
+ for ( const temporaryFilePath of temporaryFilePaths ) {
86
+
87
+ fileName = basename( temporaryFilePath )
88
+ bundleFileName = fileName.replace( '.tmp.', '.bundle.' )
89
+ bundleFilePath = join( outputDir, bundleFileName )
90
+
91
+ try {
92
+
93
+ configuration.input = temporaryFilePath
94
+ configuration.output.file = bundleFilePath
95
+
96
+ const bundle = await rollup( configuration )
97
+ const { output } = await bundle.generate( configuration.output )
98
+
99
+ let code = output[ 0 ].code
100
+ if ( code.length > 1 ) {
101
+ log( red( `[${ bundleFileName }] contain side-effects !` ) )
102
+ await bundle.write( configuration.output )
103
+ } else {
104
+ log( green( `[${ bundleFileName }] is side-effect free.` ) )
105
+ }
106
+
107
+ } catch ( error ) {
108
+
109
+ log( red( error.message ) )
110
+
111
+ }
112
+ }
113
+
114
+ } catch ( error ) {
115
+ log( red( error.message ) )
116
+ } finally {
117
+
118
+ done()
119
+
120
+ }
121
+
122
+ }
123
+ checkBundlingFromEsmBuildImportTask.displayName = basename( import.meta.filename, '.task.mjs' )
124
+ checkBundlingFromEsmBuildImportTask.description = 'Verify that the project esm build is correctly importable in third party esm files'
125
+ checkBundlingFromEsmBuildImportTask.flags = null
126
+
127
+ export { checkBundlingFromEsmBuildImportTask }