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

New Assets Build Tool (Assets Manager) #17262

Open
wants to merge 164 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 140 commits
Commits
Show all changes
164 commits
Select commit Hold shift + click to select a range
b4d57c8
Asset build tool
Skrypt Apr 4, 2024
0a226e7
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Apr 12, 2024
e0d37a9
wip yarn build
Skrypt Apr 12, 2024
0c7f561
WIP Asset Build Tool
Skrypt Dec 19, 2024
4354f70
wip AdminMenu Assets.json
Skrypt Dec 19, 2024
979fcf1
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Dec 19, 2024
7857435
wip Build Tool
Skrypt Dec 19, 2024
e045ae5
update SRI
Skrypt Dec 19, 2024
f475527
Use yarn for testing build assets
Skrypt Dec 19, 2024
18ba519
add corepack
Skrypt Dec 19, 2024
b424cde
yarn build instead of rebuild
Skrypt Dec 19, 2024
3314011
Rebuild all
Skrypt Dec 20, 2024
e476a06
Fix CI build
Skrypt Dec 20, 2024
c7325f3
CorePack
Skrypt Dec 20, 2024
e57bc54
Remove postinstall
Skrypt Dec 20, 2024
88510d2
build
Skrypt Dec 20, 2024
e5654ea
update yarn.lock
Skrypt Dec 20, 2024
ab69a7b
Adding gulp process as part of concurently
Skrypt Dec 20, 2024
0a3fc8f
remove gulp-rebuild
Skrypt Dec 20, 2024
3f75b7f
yarn build -g
Skrypt Dec 20, 2024
ab67333
Use gulp rebuild
Skrypt Dec 20, 2024
c3e10e3
Add command options
Skrypt Dec 20, 2024
d93a0cb
Update .scripts/assets-build-tool/Readme.md
Skrypt Dec 21, 2024
ed0c52a
Revert changes in OC.AdminMenu
Skrypt Dec 21, 2024
f854e18
Merge branch 'skrypt/asset-build-tool' of https://github.com/OrchardC…
Skrypt Dec 21, 2024
6bec184
Fix build under linux
Skrypt Jan 6, 2025
9e409c9
use old gulp rebuild
Skrypt Jan 6, 2025
5d63fbc
revert last commit
Skrypt Jan 6, 2025
1f5e8fa
revert
Skrypt Jan 6, 2025
7b97f88
keep npm install for gulp
Skrypt Jan 6, 2025
d5bc9f9
revert assets.json
Skrypt Jan 6, 2025
b225478
update pl
Skrypt Jan 6, 2025
5d6e58a
fix build
Skrypt Jan 6, 2025
96225f6
update yarn.lock
Skrypt Jan 6, 2025
e2ea2af
up pack.jso
Skrypt Jan 6, 2025
28a0c61
yarn cache clean
Skrypt Jan 6, 2025
e74955a
fix assets.json paths
Skrypt Jan 6, 2025
cb54b23
update assets paths
Skrypt Jan 6, 2025
99823ee
fix gulp rebuild
Skrypt Jan 6, 2025
a0dc560
use yarn build -gr
Skrypt Jan 6, 2025
c77e701
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Jan 6, 2025
8d5517b
Use GulpAssets.json and Assets.json
Skrypt Jan 8, 2025
119913b
Add missing dependencies in package.json files
Skrypt Jan 8, 2025
4f71a9b
Add null check on Parcel Bundles
Skrypt Jan 8, 2025
52c1b2b
Add default destination path for sass.mjs
Skrypt Jan 8, 2025
2995718
Null check on asset group name
Skrypt Jan 8, 2025
e53a7ac
Remove root package-lock.json file
Skrypt Jan 8, 2025
68c8202
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Jan 8, 2025
074da60
Upgrade build tool dependencies
Skrypt Jan 8, 2025
e3d4cbf
OrchardCore.Resources move to new Assets.json
Skrypt Jan 8, 2025
10187bb
Add retry logic to Concurrently
Skrypt Jan 8, 2025
fd7c476
update yarn.lock
Skrypt Jan 8, 2025
7b19fe8
Migrate OrchardCore.Resources assets
Skrypt Jan 8, 2025
0422ac6
Revert rename assets.json files
Skrypt Jan 9, 2025
3042b25
WIP Migrate to Assets2.json
Skrypt Jan 9, 2025
2fc2e86
Default to /wwwroot/Scripts
Skrypt Jan 9, 2025
10976af
Rename folder with Uppercase
Skrypt Jan 9, 2025
2f47d39
Update tags
Skrypt Jan 9, 2025
e7c1afc
Add \r\n on map EOF
Skrypt Jan 9, 2025
9048f64
test
Skrypt Jan 9, 2025
f78da9c
use \n
Skrypt Jan 9, 2025
142db4e
Remove folder
Skrypt Jan 9, 2025
4795c60
Add back folder
Skrypt Jan 9, 2025
ce09ff9
use \n in source map files
Skrypt Jan 9, 2025
c5a0eac
replace crlf with lf
Skrypt Jan 9, 2025
8ea0719
use gitattributes for eol
Skrypt Jan 9, 2025
ef59521
Update .gitattributes
Skrypt Jan 9, 2025
79a4125
update map files
Skrypt Jan 9, 2025
5192ddb
Merge branch 'skrypt/asset-build-tool' of https://github.com/OrchardC…
Skrypt Jan 9, 2025
23792df
update gitattributes
Skrypt Jan 9, 2025
9878aea
remove
Skrypt Jan 9, 2025
e8c9414
add back
Skrypt Jan 9, 2025
da4b149
add back gitatt
Skrypt Jan 9, 2025
cfa3af3
gitatt
Skrypt Jan 9, 2025
eaf8237
gitatt
Skrypt Jan 9, 2025
23650c7
rem
Skrypt Jan 9, 2025
627c918
add
Skrypt Jan 9, 2025
6ebac66
Migrate some themes
Skrypt Jan 10, 2025
743f9ba
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Jan 10, 2025
5d4a1eb
Adding PostCSS-LTR
Skrypt Jan 10, 2025
86948be
fix
Skrypt Jan 10, 2025
3999163
Fix again
Skrypt Jan 10, 2025
782a8a2
fix js map
Skrypt Jan 10, 2025
6071ac5
update from linux
Skrypt Jan 11, 2025
7b3d8ea
Refactor OC.Setup with Typescript
Skrypt Jan 11, 2025
f4adea5
More migration to Asset2
Skrypt Jan 11, 2025
dbfe1a9
Format .cshtml
Skrypt Jan 11, 2025
42f5c7a
Update workspaces
Skrypt Jan 11, 2025
bdb9cfa
Add common frontend workspace
Skrypt Jan 11, 2025
9f5d234
Rename to password-strenght.ts
Skrypt Jan 11, 2025
8d56b55
Migrate OC.Themes
Skrypt Jan 11, 2025
0021d56
WIP migration
Skrypt Jan 17, 2025
803bf7e
WIP ts migration
Skrypt Jan 21, 2025
a86a5a8
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Jan 21, 2025
578d1cb
Fix Media Gallery not displaying
Skrypt Jan 21, 2025
1c25005
Remove .map files
Skrypt Jan 21, 2025
9a5c043
.map only on development
Skrypt Jan 21, 2025
2e075c6
Remove
Skrypt Jan 21, 2025
cde492c
fix build
Skrypt Jan 21, 2025
2835695
Fix Media app
Skrypt Jan 21, 2025
6aacce9
Fix File App
Skrypt Jan 21, 2025
cad3e54
Migrate OrchardCore.Workflows
Skrypt Jan 21, 2025
6d8e081
Move package.json, remove lock
Skrypt Jan 21, 2025
7b09bce
Remove package-lock.json files
Skrypt Jan 21, 2025
7c13411
remove workspaces globs
Skrypt Jan 25, 2025
35a108e
Add watcher on sass action
Skrypt Jan 25, 2025
df9c4ab
use GulpAssets.json and Assets.json
Skrypt Jan 25, 2025
5685a43
Add Webpack action
Skrypt Feb 3, 2025
70dcfa6
Add Vite
Skrypt Feb 3, 2025
8c366a1
Add Vite Example in Media module
Skrypt Feb 3, 2025
cbe94c8
Vite watcher
Skrypt Feb 3, 2025
17cc0ed
Add host scripts for Vite
Skrypt Feb 3, 2025
7842aa4
Fix vite.config.ts example
Skrypt Feb 3, 2025
100bb49
Build on Linux
Skrypt Feb 3, 2025
b8b584a
Build all on linux
Skrypt Feb 3, 2025
956d8d8
Remove OrchardCore.Modules root folder workspace glob
Skrypt Feb 4, 2025
7dae9ad
AuditTrail Diffviewer migration
Skrypt Feb 4, 2025
dcf6f7c
Add host action to Parcel
Skrypt Feb 4, 2025
ab5bf65
Add Webpack watch and host
Skrypt Feb 5, 2025
dfa9ba7
Update yarn.lock
Skrypt Feb 5, 2025
01dbe67
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Feb 5, 2025
1fa84be
Migrate TheAdmin
Skrypt Feb 5, 2025
cb4ed6a
Rename to Assets Manager
Skrypt Feb 5, 2025
afa14c9
update build.mjs
Skrypt Feb 5, 2025
2f4ddb4
Update Documentation and fix SASS watcher
Skrypt Feb 7, 2025
23199ad
fix sass watcher
Skrypt Feb 7, 2025
7b39fad
remove
Skrypt Feb 7, 2025
bdbacaa
rename
Skrypt Feb 7, 2025
71fc261
Update Documentation
Skrypt Feb 7, 2025
cad9345
Documentation
Skrypt Feb 7, 2025
f480902
Merge branch 'main' into skrypt/asset-build-tool
Skrypt Feb 7, 2025
7ce57ce
Document Vite example
Skrypt Feb 7, 2025
407fa32
Doc
Skrypt Feb 7, 2025
e617958
Vite Getting Started doc
Skrypt Feb 7, 2025
c40ea58
Parcel Bundling
Skrypt Feb 7, 2025
7a5449f
Adjust setup password popover styles
Skrypt Feb 12, 2025
c4e740e
full yarn build -gr
Skrypt Feb 12, 2025
58bce09
Fix admin menu icon picker
Skrypt Feb 12, 2025
716b0c9
fix build
Skrypt Feb 12, 2025
8d47e13
fix build
Skrypt Feb 12, 2025
5e4b9d3
Typos
Piedone Feb 13, 2025
fadd012
add eslint config
Skrypt Feb 13, 2025
1c34040
add yarn check (vue-tsc)
Skrypt Feb 13, 2025
c389b80
Update src/docs/guides/README.md
Skrypt Feb 13, 2025
d086276
Apply suggested changes
Skrypt Feb 13, 2025
0ee6aed
Merge branch 'skrypt/asset-build-tool' of https://github.com/OrchardC…
Skrypt Feb 13, 2025
358840e
typo
Skrypt Feb 13, 2025
24ed014
Remove unnecessary files
Skrypt Feb 13, 2025
fbf2644
Remove unnecessary files
Skrypt Feb 13, 2025
f760861
React to comments
Skrypt Feb 13, 2025
e094ad3
Upgrading with yarn upgrade-interactive
Skrypt Feb 13, 2025
32bb473
Update src/docs/releases/3.0.0.md
Skrypt Feb 15, 2025
2ad43ad
Fix admin-menu-icon-picker using min action
Skrypt Feb 15, 2025
f36b07a
Merge branch 'skrypt/asset-build-tool' of https://github.com/OrchardC…
Skrypt Feb 15, 2025
3d156e7
update yarn.lock
Skrypt Feb 15, 2025
69981e6
doc
Skrypt Feb 15, 2025
5106d07
doc
Skrypt Feb 15, 2025
3db894c
use OC.Resource jquery.nested...
Skrypt Feb 15, 2025
e8a3973
Do not allow watch all
Skrypt Feb 15, 2025
8788273
Create .esproj projects
Skrypt Feb 15, 2025
1c9970f
Remove esproj
Skrypt Feb 15, 2025
d140670
Clarifying docs
Piedone Feb 15, 2025
76cd7c9
Clarifying yarn install
Piedone Feb 15, 2025
edcfc56
Watch docs
Piedone Feb 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
* text=auto

*.map text eol=lf
Skrypt marked this conversation as resolved.
Show resolved Hide resolved
**/wwwroot/Scripts/* linguist-vendored
6 changes: 4 additions & 2 deletions .github/workflows/assets_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ jobs:
- uses: actions/checkout@v4
- name: Rebuild packages
run: |
npm install
gulp rebuild
npm install -g corepack
corepack enable
yarn
yarn build -gr
Skrypt marked this conversation as resolved.
Show resolved Hide resolved
- name: Check if git has changes
shell: pwsh
run: |
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ nuget.exe
#exclude node modules
node_modules/

#exclude yarn
.yarn

#exclude parcel
.parcel-cache

#exclude .map files
*.map

wwwroot
**/Localization/**/*.po
!test/OrchardCore.Tests/Localization/**/*.po
Expand Down
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "all",
"tabWidth": 2,
Piedone marked this conversation as resolved.
Show resolved Hide resolved
"semi": true,
"printWidth": 180
}
1 change: 1 addition & 0 deletions .scripts/assets-manager/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
7 changes: 7 additions & 0 deletions .scripts/assets-manager/.parcelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@parcel/config-default",
"resolvers": ["@parcel/resolver-glob", "..."],
"optimizers": {
"*.{js,mjs,cjs}": ["@parcel/optimizer-terser"]
}
}
1 change: 1 addition & 0 deletions .scripts/assets-manager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[Assets Manager documentation](../../src/docs/guides/assets-manager/README.md)
44 changes: 44 additions & 0 deletions .scripts/assets-manager/assetGroups.mjs
Piedone marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { glob } from 'glob'
import JSON5 from "json5";
import fs from "fs-extra";
import path from "path";

import buildConfig from "./config.mjs";

// get's an object representation of all Assets.json in the solution
export default function getAllAssetGroups() {
var assetGroups = [];
getAssetsJsonPaths().forEach(function (assetManifestPath) {
var assetManifest = JSON5.parse(fs.readFileSync(assetManifestPath, "utf-8"));
assetManifest.forEach(function (assetGroup) {
resolveAssetGroupPaths(assetGroup, assetManifestPath);
assetGroups.push(assetGroup);
});
});
return assetGroups;
}

// Expands the paths to full paths.
function resolveAssetGroupPaths(assetGroup, assetManifestPath) {
assetGroup.manifestPath = assetManifestPath;
assetGroup.basePath = path.dirname(assetManifestPath);
if (assetGroup.source) {
assetGroup.originalSource = assetGroup.source;
// since node_modules all resolve at the root (because of yarn)
if (assetGroup.source.startsWith("node_modules")) {
assetGroup.source = path.resolve(path.join(process.cwd(), assetGroup.source)).replace(/\\/g, "/");
} else {
assetGroup.source = path.resolve(path.join(assetGroup.basePath, assetGroup.source)).replace(/\\/g, "/");
}
// The source path relative to the root of the solution.
assetGroup.relativeSource = assetGroup.source.substring(process.cwd().length);

}
if (assetGroup.dest) {
assetGroup.dest = path.resolve(path.join(assetGroup.basePath, assetGroup.dest)).replace(/\\/g, "/");
}
}

function getAssetsJsonPaths() {
return glob.sync(buildConfig("assetsLookupGlob"), {});
}
249 changes: 249 additions & 0 deletions .scripts/assets-manager/build.mjs
Copy link
Member

@Piedone Piedone Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got the same diff in all the staged files after running watch.
{27A84D7F-719D-40D4-83B3-475C0C367CD5}

And also:

{AD509DC6-6F9D-4DDE-A3C1-83EC67592473}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, watch will create unminified assets. You should not commit these, the watcher is for developping only.

Copy link
Member

@Piedone Piedone Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not how I'd expect this to work, but rather that watch does the same as build, i.e. it generates the end build output, but automatically on save. Like dotnet watch. Our project does the same for static assets.

The developer story needs to be streamlined here, with a quick and simple inner loop, and these tools shouldn't generate any changes which are not gitignored but mustn't be committed, that's confusing.

I can see that in order to be fast, watch potentially does less than build, that's OK, but then the files it generates which are not needed should be gitignored (the ones in dist, although why are those generated in the first place?). If indeed, then then it should only update the non-minified debug version of the files, and leave the minified ones untouched (yesterday we talked about potentially only using minified files with source maps, what we can do, but we don't need to jump that gun right now). Then build can generate both debug and minified. And all of this needs to be told to the contributors, see #17262 (comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The watcher needs to output something really quick on save. So, by design these compilers will never minimize and optimize the code. That's how these tools works. They have a production and developper mode which are triggered when using watch or build with them.

Of course, you never commit a watch to your repository.

I can take a look at Parcel configurations but right now I don't think we could output unminified/un-optimized assets along with a minified/optimized asset on each build. Parcel has a "mode" config parameter that is set to either development or production which will create either an unminified or minified asset. And when we do build it will set the mode to production. When we watch it will set it to development. Else, I don't think there is any other way to tell it to create a minified asset unless doing it manually with another Parcel process. But that will add up compilation time while the tool always worked like this.

Copy link
Contributor Author

@Skrypt Skrypt Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe Vite and Webpack would work because we have a configuration file that is editable with them. But that's up to the dev at that point.

Basically, what I'm saying is that these use cases are all possible and even if we are trying to restrict something here it will probably eventually be worst.

Copy link
Contributor Author

@Skrypt Skrypt Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the ability to do yarn watch without specifying the asset name with yarn watch -n modulename
Else it was doing a watch all which is not a good idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added docs about this too.

Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
import JSON5 from "json5";
import fs from "fs-extra";
import path from "path";
import chalk from "chalk";
import concurrently from "concurrently";
import { fileURLToPath } from "url";
import parseArgs from "minimist";
import _ from "lodash";

import buildConfig from "./config.mjs";
import clean from "./clean.mjs";
import getAllAssetGroups from "./assetGroups.mjs";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// eslint-disable-next-line no-unused-vars
let parsedArgs = parseArgs(process.argv.slice(2));

let task = parsedArgs._[0];

if (!task) {
task = "build";
}
console.log(chalk.green("Task: ", task));

let groups = getAllAssetGroups();

// Filter the packages if the user passes the -n cli flag
let packagesStr = parsedArgs.n;
if (packagesStr != undefined) {
const packages = packagesStr.split(" ");
if (packages.length > 0) {
console.log(chalk.yellow("Filtering groups based on packages: "), packages.join(", "));
groups = groups.filter((g) => packages.includes(g.name));
}
}

// Filter the tags if the user passes the -t cli flag
let tagsStr = parsedArgs.t;
if (tagsStr != undefined) {
const tags = tagsStr.split(" ");
if (tags.length > 0) {
console.log(chalk.yellow("Filtering groups based on tag: "), tags.join(", "));
groups = groups.filter((g) => {
if (Array.isArray(g.tags)) {
return _.intersection(tags, g.tags)?.length > 0;
} else {
return tags.includes(g.tags);
}
});
}
}

// Filter the tags if the user passes the -b cli flag
let bundleStr = parsedArgs.b;
if (bundleStr != undefined) {
console.log(chalk.yellow("Filtering groups for orchardcore-bundle"));
groups = groups.filter((g) => g.bundleEntrypoint);
}

if (task === "clean") {
const returnCode = await clean(groups);
process.exit(returnCode);
}

if (task === "build" || task === "watch" || task === "host") {
// Group the parcel groups by bundle
const parcelGroupsByBundle = _.groupBy(
groups.filter((g) => g.bundleEntrypoint),
(g) => g.bundleEntrypoint,
);

// Remove those groups from the groups array as we will push new bundled groups instead.
groups = groups.filter((g) => !g.bundleEntrypoint);

if (parcelGroupsByBundle) {
const entries = [];
// loop through each bundle and generate the new combined group
_.forEach(parcelGroupsByBundle, (value, bundleEntrypoint) => {
// generate a file that will be the main import for this group
const bundleImports = _.map(value, (g) => `import "${g.relativeSource}";`).join("\n");
const importPath = path.join(__dirname, `dist/${bundleEntrypoint}.js`);
fs.outputFileSync(importPath, bundleImports, "utf8"); //bury this folder
entries.push(importPath);
});

const parcelBundleOutput = buildConfig("parcelBundleOutput");
if (entries.length > 0) {
console.log(chalk.yellow("Building Parcel bundles: "), _.keys(parcelGroupsByBundle).join(", "));

groups.push({
action: "parcel",
name: `orchardcore-bundle`,
source: entries,
dest: parcelBundleOutput,
});
}
}
}

const buildProcesses = groups
.map((group) => {
//b64 encode the command group for the next process. Was easier to pass the group json to the subprocess
const encodedGroup = Buffer.from(JSON5.stringify(group)).toString("base64");
switch (group.action) {
case "parcel":
// parcel only handles build and watch
if (!(task === "build" || task === "watch" || task === "host")) {
console.log(chalk.yellow(`Parcel action does not handle build type: ${task} for ${group.name}`));
break;
}
return {
order: group.order,
name: group.name ?? "PARCEL",
command: `node ${path.join(__dirname, "parcel.mjs")} ${task} ${encodedGroup}`,
};
case "webpack":
// parcel only handles build and watch
if (!(task === "build" || task === "watch" || task === "host")) {
console.log(chalk.yellow(`Webpack action does not handle build type: ${task} for ${group.name}`));
break;
}
return {
order: group.order,
name: group.name ?? "WEBPACK",
command: `node ${path.join(__dirname, "webpack.mjs")} ${task} ${encodedGroup}`,
};
case "vite":
// parcel only handles build and watch
if (!(task === "build" || task === "watch" || task === "host")) {
console.log(chalk.yellow(`Vite action does not handle build type: ${task} for ${group.name}`));
break;
}
return {
order: group.order,
name: group.name ?? "VITE",
command: `node ${path.join(__dirname, "vite.mjs")} ${task} ${encodedGroup}`,
};
case "run":
const script = group?.scripts[task]; //get's the script that matches the current type of command (build/watch or others)
if (script) {
const cmd = {
order: group.order,
name: group.name ?? "RUN",
command: `cd ${group.source} && ${script}`,
};
console.log("run command: ", cmd);
return cmd;
}
console.log(chalk.yellow(group.name, "run action does not have a script for build type: ", task));
break;
case "copy":
if (task === "copy" || task === "build" || task === "dry-run") {
return {
order: group.order,
name: group.name ?? "COPY",
command: `node ${path.join(__dirname, "copy.mjs")} ${task} ${encodedGroup}`,
};
}
console.log(chalk.yellow("Use copy or build type to copy files from group: ", group.name));
break;
case "min":
if (task === "build" || task === "dry-run") {
return {
order: group.order,
name: group.name ?? "MIN",
command: `node ${path.join(__dirname, "min.mjs")} ${task} ${encodedGroup}`,
};
}
console.log(chalk.yellow("Use min or build type to minify files from group: ", group.name));
break;
case "sass":
if (task === "build" || task === "watch") {
return {
order: group.order,
name: group.name ?? "SASS",
command: `node ${path.join(__dirname, "sass.mjs")} ${task} ${encodedGroup}`,
};
}
console.log(chalk.yellow("Use sass or build type to transpile/minify files from group: ", group.name));
break;
default:
console.log(chalk.yellow("The following group was not handled by our build process"), group.name);
break;
}
})
.filter((el) => el != undefined); // remove undefined entries

// Add the gulp build process if the user passes the -g cli flag
let gulpBuildStr = parsedArgs["g"];
let gulpRebuildStr = parsedArgs["r"];

if (gulpBuildStr != undefined && gulpRebuildStr == undefined) {
buildProcesses.push({
order: 0,
name: "gulp build",
command: `gulp build`,
});
} else if (gulpBuildStr != undefined && gulpRebuildStr != undefined) {
buildProcesses.push({
order: 0,
name: "gulp rebuild",
command: `gulp rebuild`,
});
}

if (buildProcesses.length <= 0) {
console.log(chalk.yellow("Nothing to build, exiting..."));
process.exit(0);
}

// run all builds in parallel. I chose to use concurrently here as it does nice colors + console log prefixes
const { result } = concurrently(
buildProcesses.sort(function (a, b) {
return a.order - b.order;
}),
{
restartTries: 3,
prefixColors: ["green", "yellow", "blue", "magenta", "cyan", "greenBright", "yellowBright", "blueBright", "magentaBright", "cyanBright"],
},
);

result.then(
() => {
console.log(chalk.bold.green("Success !"));
process.exit(0);
},
(closeEvents) => {
let actualErrors = false;

closeEvents.forEach((evt) => {
//3221225477 is an intermittent issue with windows ? and does not seem to represent an actual issue.
if (evt.exitCode != 0 && evt.exitCode != 3221225477) {
console.log(chalk.red(evt.command.name, "exited with code", evt.exitCode));
actualErrors = true;
} else if (evt.exitCode == 3221225477) {
console.log(chalk.yellow(evt.command.name, "exited with code", evt.exitCode));
}
});

if (actualErrors) {
console.log(chalk.bold.redBright("Errors occurred!"));
process.exit(1);
} else {
process.exit(0);
}
},
);
45 changes: 45 additions & 0 deletions .scripts/assets-manager/clean.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import chalk from "chalk";
import path from "path";
import fs from "fs-extra";

export default async function clean(groups) {
console.log(chalk.redBright("Clean task called. This wipes all folders referenced as destinations of all groups. Waiting 3 seconds before starting."));
await new Promise((resolve) => setTimeout(resolve, 3000));
try {
const promises = [];
for (const g of groups) {
if (g.dest) {
if (!g.dest.includes("wwwroot" || !g.dest.includes("dist"))) {
console.log(chalk.red("We only support deleting folders that contain wwwroot or dist"), chalk.gray(g.dest));
throw chalk.red("Error cleaning: ") + chalk.gray(g.dest);
}

promises.push(
fs
.rm(g.dest, { recursive: true, force: true })
.then(() => console.log(chalk.green("Deleted folder:"), chalk.gray(g.dest)))
.catch((err) => {
console.log(chalk.red("Error deleting folder:"), chalk.gray(g.dest));
throw err;
})
);
}
}
const parcelCache = path.join(process.cwd(), ".parcel-cache");
promises.push(
fs
.rm(parcelCache, { recursive: true, force: true })
.then(() => console.log(chalk.green("Deleted folder:"), chalk.gray(parcelCache)))
.catch((err) => {
console.log(chalk.red("Error deleting folder:"), chalk.gray(parcelCache));
throw err;
})
);
await Promise.all(promises);
console.log(chalk.green("Cleaned successfully! exiting..."));
return 0;
} catch (e) {
console.log(chalk.red("Error: "), e);
return 1;
}
}
Loading