├── .all-contributorsrc
├── .github
└── workflows
│ ├── nodejs.yml
│ └── npm-publish.yml
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── analyze
├── index.ts
├── schema.d.ts
└── schema.json
├── builders.json
├── collection.json
├── index.ts
├── ng-add
├── index.ts
├── schema.json
├── schema.ts
└── workspace.ts
├── package.json
├── renovate.json
└── tsconfig.json
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "files": [
3 | "README.md"
4 | ],
5 | "imageSize": 100,
6 | "commit": false,
7 | "contributors": [
8 | {
9 | "login": "AnkitSharma-007",
10 | "name": "Ankit",
11 | "avatar_url": "https://avatars1.githubusercontent.com/u/33789321?v=4",
12 | "profile": "https://ankitsharmablogs.com/",
13 | "contributions": [
14 | "doc"
15 | ]
16 | },
17 | {
18 | "login": "twittwer",
19 | "name": "Tobias Wittwer",
20 | "avatar_url": "https://avatars1.githubusercontent.com/u/8677948?v=4",
21 | "profile": "https://github.com/twittwer",
22 | "contributions": [
23 | "doc"
24 | ]
25 | },
26 | {
27 | "login": "BhavikCpatel",
28 | "name": "Bhavik",
29 | "avatar_url": "https://avatars3.githubusercontent.com/u/8742935?v=4",
30 | "profile": "https://github.com/BhavikCpatel",
31 | "contributions": [
32 | "code"
33 | ]
34 | },
35 | {
36 | "login": "patelvimal",
37 | "name": "vimal patel",
38 | "avatar_url": "https://avatars.githubusercontent.com/u/6451223?v=4",
39 | "profile": "http://patelvimal.github.io",
40 | "contributions": [
41 | "code"
42 | ]
43 | }
44 | ],
45 | "contributorsPerLine": 7,
46 | "projectName": "source-map-analyzer",
47 | "projectOwner": "ngx-builders",
48 | "repoType": "github",
49 | "repoHost": "https://github.com",
50 | "skipCi": true
51 | }
52 |
--------------------------------------------------------------------------------
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [16.x]
20 |
21 | steps:
22 | - uses: actions/checkout@v3
23 | - name: Use Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v3
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 | - run: npm install
28 | - run: npm run build
29 | env:
30 | CI: true
31 |
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3 |
4 | name: Publish Package
5 |
6 | on:
7 | release:
8 | types: [published]
9 |
10 | jobs:
11 | publish-npm:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | - uses: actions/setup-node@v3
16 | with:
17 | node-version: 16
18 | registry-url: https://registry.npmjs.org/
19 | scope: '@ngx-builders'
20 | - run: npm i
21 | - run: npm run build
22 | - run: npm publish
23 | env:
24 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | *.map
3 | node_modules
4 | package-lock.json
5 | dist
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ngx-builders/source-map-analyzer/751bc6d3c4912c7248173e605cf00cb7ed5d6743/.npmignore
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 ngx-builders
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://badge.fury.io/js/%40ngx-builders%2Fanalyze)
4 | 
5 | [](https://www.npmjs.com/package/@ngx-builders/analyze)
6 |
7 | # Builder To Run Source Map Explorer
8 |
9 | [](#contributors-)
10 |
11 |
12 | Want to run the source-map-explorer with Angular?
13 | This builder does it for you with zero configuration.
14 |
15 |
16 | ## Setting up this Builder
17 |
18 | ```
19 | ng add @ngx-builders/analyze
20 | OR
21 | ng add @ngx-builders/analyze --project={projectName}
22 | ```
23 |
24 | NOTE: This version uses npx to install source-map-explorer temporarily if it isn't installed already. If you don't have npx installed, please install it.
25 |
26 |
27 | We will remove this dependecny in future updates.
28 |
29 | ## That's it. Now, you are good to go
30 |
31 | Now whenever you want to analyze your angular project just run a command `ng run [YOUR_PROJECT_NAME]:analyze` and it will run the source-map-explorer.
32 |
33 |
34 | ## 📦 Options
35 |
36 |
37 | #### --gzip
38 | - **optional**
39 | - Default: `false` (boolean)
40 | - Example:
41 | - `ng run [YOUR_PROJECT_NAME]:analyze --gzip` – Give the stats of gzip bundle.
42 |
43 |
44 | #### --diffLoading
45 | - **optional**
46 | - Default: `false` (boolean)
47 | - Example:
48 | - `ng run [YOUR_PROJECT_NAME]:analyze --diffLoading=true` – You can change to true if differential loading is enabled.
49 |
50 | # License
51 | [MIT](https://github.com/ngx-builders/source-map-analyzer/blob/master/LICENSE)
52 |
53 |
54 | ## Contributors ✨
55 |
56 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
57 |
58 |
59 |
60 |
61 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
76 |
--------------------------------------------------------------------------------
/analyze/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | BuilderOutput,
3 | createBuilder,
4 | BuilderContext,
5 | } from "@angular-devkit/architect";
6 | import { Schema } from "./schema";
7 | import util from "util";
8 | import { exec } from "child_process";
9 |
10 | export const execAsync = util.promisify(exec);
11 |
12 | export default createBuilder(
13 | async (
14 | builderConfig: Schema,
15 | context: BuilderContext
16 | ): Promise => {
17 | try {
18 | context.reportStatus(`Starting Report generation...🚀`);
19 |
20 | const mainFile = "*.js";
21 | let explorerCommand = `npx source-map-explorer ${builderConfig.outputPath}/${mainFile}`;
22 | if (builderConfig.gzip) {
23 | explorerCommand = `${explorerCommand} --gzip`;
24 | }
25 | if(builderConfig.reportPath) {
26 | const reportFormat = builderConfig.reportFormat || 'html';
27 | explorerCommand = `${explorerCommand} --${reportFormat} ${builderConfig.reportPath}/${context?.target?.project}.html`;
28 | }
29 | const { stdout, stderr } = await execAsync(explorerCommand);
30 | context.logger.info(stdout);
31 | context.logger.info(stderr);
32 |
33 | context.reportStatus(`Done.`);
34 | return {
35 | success: true,
36 | };
37 | } catch (e: any) {
38 | return {
39 | error: e.message,
40 | success: true,
41 | };
42 | }
43 | }
44 | );
45 |
--------------------------------------------------------------------------------
/analyze/schema.d.ts:
--------------------------------------------------------------------------------
1 | export interface Schema {
2 | outputPath: string;
3 | gzip?: boolean;
4 | reportPath?: string;
5 | reportFormat: 'html' | 'json' | 'tsv' ;
6 | }
--------------------------------------------------------------------------------
/analyze/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "$id": "source-map-analyze",
4 | "type": "object",
5 | "properties": {
6 | "gzip": {
7 | "type": "boolean"
8 | },
9 | "outputPath": {
10 | "type": "string"
11 | },
12 | "reportPath": {
13 | "type": "string"
14 | },
15 | "reportFormat": {
16 | "type": "string",
17 | "default": "html"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/builders.json:
--------------------------------------------------------------------------------
1 | {
2 | "builders": {
3 | "analyze": {
4 | "implementation": "./analyze",
5 | "schema": "./analyze/schema.json",
6 | "description": "Runs the analyzer."
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/collection.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "ng-add": {
5 | "description": "Builder to analyze package using source-map-explorer",
6 | "factory": "./ng-add/index#ngAdd",
7 | "schema": "./ng-add/schema.json",
8 | "aliases": [
9 | "install"
10 | ]
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | export * from './ng-add';
2 | export * from './analyze';
--------------------------------------------------------------------------------
/ng-add/index.ts:
--------------------------------------------------------------------------------
1 | import { TargetDefinition } from '@angular-devkit/core/src/workspace';
2 | import { chain, Rule, SchematicsException, Tree } from '@angular-devkit/schematics';
3 | import { NgAddOptions } from './schema';
4 | import { getWorkspace, updateWorkspace } from './workspace';
5 |
6 |
7 | export function ngAdd(options: NgAddOptions): Rule {
8 | return async (host: Tree) => {
9 | const workspace = await getWorkspace(host);
10 |
11 | // Get project name
12 | if (!options.project) {
13 | if (workspace.extensions.defaultProject) {
14 | options.project = workspace.extensions.defaultProject as string;
15 | } else {
16 | throw new SchematicsException(
17 | 'No Angular project selected or you are in a Nx workspace'
18 | );
19 | }
20 | }
21 |
22 | // Validating project name
23 | const project = workspace.projects.get(options.project);
24 | if (!project) {
25 | throw new SchematicsException(`The specified Angular project is not defined in this workspace`);
26 | }
27 |
28 | // Checking if it is application
29 | if (project.extensions['projectType'] !== 'application') {
30 | throw new SchematicsException(`source-map-analyzer requires an Angular project type of "application" in angular.json`);
31 | }
32 |
33 | const outputPath: string | undefined = project.targets.get('build')?.options?.outputPath as string;
34 |
35 | if (!outputPath) {
36 | const message: string = `Cannot read the output path(architect.build.options.outputPath) of the Angular project "${options.project}" in angular.json`;
37 | throw new SchematicsException(message);
38 | }
39 |
40 | var targetDefinition: TargetDefinition = {
41 | builder: "@ngx-builders/analyze:analyze",
42 | options: {
43 | outputPath: outputPath
44 | }
45 | }
46 |
47 | project.targets.add({ name: 'analyze', ...targetDefinition });
48 |
49 | return chain([updateWorkspace(workspace)]);
50 | };
51 | }
52 |
--------------------------------------------------------------------------------
/ng-add/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "$id": "source-map-explore",
4 | "title": "Builder to analyze using source-map-explorer",
5 | "type": "object",
6 | "properties": {
7 | "project": {
8 | "type": "string",
9 | "description": "The name of the project.",
10 | "$default": {
11 | "$source": "projectName"
12 | }
13 | }
14 | },
15 | "required": []
16 | }
17 |
--------------------------------------------------------------------------------
/ng-add/schema.ts:
--------------------------------------------------------------------------------
1 | export interface NgAddOptions {
2 | project: string | undefined;
3 | }
4 |
--------------------------------------------------------------------------------
/ng-add/workspace.ts:
--------------------------------------------------------------------------------
1 | import { virtualFs, workspaces } from '@angular-devkit/core';
2 | import { noop, Rule, SchematicsException, Tree } from '@angular-devkit/schematics';
3 |
4 | /* Below code reference is taken from Angular CLI project.
5 | https://github.com/angular/angular-cli/blob/master/packages/schematics/angular/utility/workspace.ts
6 |
7 | These methods are not part of public APIs so we should not be referencing those methods.
8 | that's why added below method here.
9 | */
10 |
11 | function createHost(tree: Tree): workspaces.WorkspaceHost {
12 | return {
13 | async readFile(path: string): Promise {
14 | const data = tree.read(path);
15 | if (!data) {
16 | throw new SchematicsException('File not found.');
17 | }
18 | return virtualFs.fileBufferToString(data);
19 | },
20 | async writeFile(path: string, data: string): Promise {
21 | return tree.overwrite(path, data);
22 | },
23 | async isDirectory(path: string): Promise {
24 | return !tree.exists(path) && tree.getDir(path).subfiles.length > 0;
25 | },
26 | async isFile(path: string): Promise {
27 | return tree.exists(path);
28 | },
29 | };
30 | }
31 |
32 | export async function getWorkspace(tree: Tree, path = '/') : Promise {
33 | const host = createHost(tree);
34 | const { workspace } = await workspaces.readWorkspace(path, host);
35 | return workspace;
36 | }
37 |
38 | export function updateWorkspace(
39 | updater: (workspace: workspaces.WorkspaceDefinition) => void | Rule | PromiseLike,
40 | ): Rule;
41 | export function updateWorkspace(workspace: workspaces.WorkspaceDefinition): Rule;
42 | export function updateWorkspace(
43 | updaterOrWorkspace:
44 | | workspaces.WorkspaceDefinition
45 | | ((workspace: workspaces.WorkspaceDefinition) => void | Rule | PromiseLike),
46 | ): Rule {
47 | return async (tree: Tree) => {
48 | const host = createHost(tree);
49 |
50 | if (typeof updaterOrWorkspace === 'function') {
51 | const { workspace } = await workspaces.readWorkspace('/', host);
52 |
53 | const result = await updaterOrWorkspace(workspace);
54 |
55 | await workspaces.writeWorkspace(workspace, host);
56 |
57 | return result || noop;
58 | } else {
59 | await workspaces.writeWorkspace(updaterOrWorkspace, host);
60 |
61 | return noop;
62 | }
63 | };
64 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@ngx-builders/analyze",
3 | "version": "5.0.0",
4 | "description": "Angular Builder To Run Source Map Explorer",
5 | "main": "index.js",
6 | "builders": "./builders.json",
7 | "schematics": "./collection.json",
8 | "ng-add": {
9 | "save": "devDependencies"
10 | },
11 | "scripts": {
12 | "copy:pacakge": "cp package.json dist",
13 | "copy:json": "cp ng-add/schema.json dist/ng-add/schema.json && cp builders.json dist/builders.json && cp collection.json dist/collection.json && cp README.md dist/README.md && cp analyze/schema.json dist/analyze/schema.json",
14 | "build": "tsc && npm run copy:pacakge && npm run copy:json"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/ngx-builders/source-map-analyzer.git"
19 | },
20 | "publishConfig": {
21 | "access": "public"
22 | },
23 | "keywords": [
24 | "angular",
25 | "schematics",
26 | "cli",
27 | "angular-cli",
28 | "netlify",
29 | "deploy",
30 | "ng run",
31 | "ng builder",
32 | "Angular Buidler"
33 | ],
34 | "author": "Santosh Yadav ",
35 | "license": "MIT",
36 | "devDependencies": {
37 | "@types/node": "20.3.1",
38 | "ts-node": "10.9.1",
39 | "typescript": "~5.1.3"
40 | },
41 | "dependencies": {
42 | "@angular-devkit/architect": "0.1601.0",
43 | "@angular-devkit/core": "16.1.0",
44 | "@angular-devkit/schematics": "16.1.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "moduleResolution": "node",
4 | "module": "commonjs",
5 | "target": "ES2020",
6 | "outDir": "dist",
7 | "lib": [
8 | "es2018"
9 | ],
10 | "strict": true,
11 | "allowSyntheticDefaultImports": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "sourceMap": false,
14 | "declaration": false,
15 | "inlineSources": false,
16 | "stripInternal": true,
17 | "skipLibCheck": true,
18 | "noImplicitAny": false,
19 | "esModuleInterop": true
20 | },
21 | "exclude": [
22 | "node_modules"
23 | ],
24 | "compileOnSave": false,
25 | "buildOnSave": false,
26 | "angularCompilerOptions": {
27 | "skipTemplateCodegen": true,
28 | "strictMetadataEmit": true,
29 | }
30 | }
--------------------------------------------------------------------------------