├── .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 | ![source-map-analyzer](https://socialify.git.ci/ngx-builders/source-map-analyzer/image?font=Raleway&forks=1&issues=1&language=1&owner=1&pattern=Charlie%20Brown&pulls=1&stargazers=1&theme=Dark) 2 | 3 | [![npm version](https://badge.fury.io/js/%40ngx-builders%2Fanalyze.svg)](https://badge.fury.io/js/%40ngx-builders%2Fanalyze) 4 | ![Node.js CI](https://github.com/ngx-builders/source-map-analyzer/workflows/Node.js%20CI/badge.svg?branch=master) 5 | [![npm downloads](https://img.shields.io/npm/dt/@ngx-builders/analyze?label=npm%20downloads)](https://www.npmjs.com/package/@ngx-builders/analyze) 6 | 7 | # Builder To Run Source Map Explorer 8 | 9 | [![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#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 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |

Ankit

📖

Tobias Wittwer

📖

Bhavik

💻

vimal patel

💻
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 | } --------------------------------------------------------------------------------