PageSourceSearch

https://projen.io/assets/js/6806a470.1f81e741.js

js projen.io collected 2026-10-02 05:17:53 UTC 12,954 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([["2718"],{3159(e,n,t){t.r(n),t.d(n,{metadata:()=>r,default:()=>p,frontMatter:()=>i,contentTitle:()=>o,toc:()=>c,assets:()=>l});var r=JSON.parse('{"id":"quick-starts/typescript/angular/index","title":"Create an Angular Application","description":"This quick start will help you create an Angular.js TypeScript application.","source":"@site/../docs/quick-starts/typescript/angular/index.md","sourceDirName":"quick-starts/typescript/angular","slug":"/quick-starts/typescript/angular/","permalink":"/docs/quick-starts/typescript/angular/","draft":false,"unlisted":false,"editUrl":"https://github.com/projen/projen/tree/main/docusaurus/../docs/quick-starts/typescript/angular/index.md","tags":[],"version":"current","sidebarPosition":3,"frontMatter":{"sidebar_position":3},"sidebar":"docsSidebar","previous":{"title":"Create an ExpressJS Application","permalink":"/docs/quick-starts/typescript/expressjs/"},"next":{"title":"Create a React Application","permalink":"/docs/quick-starts/typescript/react/"}}'),s=t(4848),a=t(8453);let i={sidebar_position:3},o="Create an Angular Application",l={},c=[{value:"Bringing it under projen management",id:"bringing-it-under-projen-management",level:2},{value:"Set up tasks",id:"set-up-tasks",level:2},{value:"project.addTask()",id:"projectaddtask",level:3},{value:"project.tasks.tryFind()?.reset()",id:"projecttaskstryfindreset",level:3},{value:"gitignore",id:"gitignore",level:2},{value:"README.md",id:"readmemd",level:2}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"create-an-angular-application",children:"Create an Angular Application"})}),"\n",(0,s.jsxs)(n.p,{children:["This quick start will help you create an ",(0,s.jsx)(n.a,{href:"https://angular.io/",children:"Angular.js"})," TypeScript application.\nWe'll be using Angular's 'Hello World' project as a starting point, then bringing it under projen\nmanagement."]}),"\n",(0,s.jsxs)(n.p,{children:["To begin, make sure you have the version of NodeJS you want to use set up in your terminal.\nRunning ",(0,s.jsx)(n.code,{children:"which node"})," in bash/zsh/other POSIX shells, or ",(0,s.jsx)(n.code,{children:"Get-Command node"})," in Powershell,\nshould print the path to the NodeJS version you want to use. ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm",children:(0,s.jsx)(n.code,{children:"nvm"})}),"\nis a popular tool for managing multiple versions of Node on a single machine.\nTo select a version, run ",(0,s.jsx)(n.code,{children:"nvm use <version>"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:"pnpm add -g @angular/cli"})," to install the Angular CLI. Next, run\n",(0,s.jsx)(n.code,{children:"pnpm dlx @angular/cli new --create-application true hello-world"})," to initialize the hello-world project.\nThen run ",(0,s.jsx)(n.code,{children:"cd hello-world"})," to enter the project directory."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"pnpm add -g @angular/cli\npnpm dlx @angular/cli new --create-application true hello-world\ncd hello-world\n"})}),"\n",(0,s.jsx)(n.p,{children:"Follow the prompts and within a few minutes, you'll get an Angular project structure with sample\ncode."}),"\n",(0,s.jsx)(n.h2,{id:"bringing-it-under-projen-management",children:"Bringing it under projen management"}),"\n",(0,s.jsx)(n.p,{children:"Now that we have a working Angular project, we'll bring it under projen management. We'll start\nby making a backup of files that will be overwritten by projen:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"mv package.json package.json.bak\nmv README.md README.md.bak\nmv .gitignore .gitignore.bak\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create a new TypeScript project, use ",(0,s.jsx)(n.code,{children:"pnpm dlx projen new typescript"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"pnpm dlx projen new typescript\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Most of the ",(0,s.jsx)(n.code,{children:"pnpm dlx projen default"})," command that runs after project initialization will work, but\nit will fail when trying to reference packages that are no longer in ",(0,s.jsx)(n.code,{children:"package.json"}),". We'll fix\nthat next."]}),"\n",(0,s.jsxs)(n.p,{children:["In your favorite editor/IDE, open ",(0,s.jsx)(n.code,{children:"package.json.bak"}),". Open ",(0,s.jsx)(n.code,{children:".projenrc.ts"})," in a separate tab or window."]}),"\n",(0,s.jsx)(n.p,{children:"You'll see a TypeScript file that looks like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:'import { typescript } from "projen";\nconst project = new typescript.TypeScriptProject({\n  defaultReleaseBranch: "main",\n  name: "hello-world",\n  projenrcTs: true,\n\n  // deps: [],                /* Runtime dependencies of this module. */\n  // description: undefined,  /* The description is just a string that helps people understand the purpose of the package. */\n  // devDeps: [],             /* Build dependencies for this module. */\n  // packageName: undefined,  /* The "name" in package.json. */\n});\nproject.synth();\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Uncomment the line starting with ",(0,s.jsx)(n.code,{children:"// deps:"})," and add the Angular dependencies from ",(0,s.jsx)(n.code,{children:"package.json.bak"}),". For example,\n",(0,s.jsx)(n.code,{children:'"@angular/animations": "^16.2.0"'})," should become ",(0,s.jsx)(n.code,{children:'"@angular/animations@^16.2.0"'}),". Do the same for ",(0,s.jsx)(n.code,{children:"devDeps"})," and\nadd them all to the appropriate place in the ",(0,s.jsx)(n.code,{children:".projenrc.ts"})," file."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"Your versions will very likely be different - convert what you get from the CLI to the format\nshown below."})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:'import { typescript } from "projen";\nconst project = new typescript.TypeScriptProject({\n  defaultReleaseBranch: "main",\n  name: "hello-world",\n  projenrcTs: true,\n\n  deps: [\n    "@angular/animations@^16.2.0",\n    "@angular/common@^16.2.0",\n    "@angular/compiler@^16.2.0",\n    "@angular/core@^16.2.0",\n    "@angular/forms@^16.2.0",\n    "@angular/platform-browser@^16.2.0",\n    "@angular/platform-browser-dynamic@^16.2.0",\n    "@angular/router@^16.2.0",\n    "rxjs@~7.8.0",\n    "tslib@^2.3.0",\n    "zone.js@~0.13.0",\n  ],\n  devDeps: [\n    "@angular-devkit/build-angular@^16.2.6",\n    "@angular/cli@^16.2.6",\n    "@angular/compiler-cli@^16.2.0",\n    "@types/jasmine@~4.3.0",\n    "jasmine-core@~4.6.0",\n    "karma@~6.4.0",\n    "karma-chrome-launcher@~3.2.0",\n    "karma-coverage@~2.2.0",\n    "karma-jasmine@~5.1.0",\n    "karma-jasmine-html-reporter@~2.1.0",\n    "typescript@~5.1.3",\n  ],\n});\nproject.synth();\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:"pnpm dlx projen"})," to install the Angular dependencies."]}),"\n",(0,s.jsx)(n.h2,{id:"set-up-tasks",children:"Set up tasks"}),"\n",(0,s.jsxs)(n.p,{children:["Next, we'll set up some task scripts to make it easier to run our Angular application. Above\nthe ",(0,s.jsx)(n.code,{children:"project.synth()"})," line, add the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:'project.addTask("ng", { execArgs: ["ng"], receiveArgs: true });\nproject.addTask("start", { execArgs: ["ng", "serve"], receiveArgs: true });\n// projen already has build, but it calls compile, which is empty\nproject.tasks.tryFind("compile")?.reset("ng build", { receiveArgs: true });\nproject.addTask("ng:watch", {\n  execArgs: ["ng", "build", "--watch", "--configuration", "development"],\n  receiveArgs: true,\n});\nproject.tasks.tryFind("test")?.reset("ng test", { receiveArgs: true });\nproject.addTask("e2e", { execArgs: ["ng", "se2e"], receiveArgs: true });\n\nproject.synth();\n'})}),"\n",(0,s.jsx)(n.p,{children:"Let's go over the two types of tasks we've added here:"}),"\n",(0,s.jsx)(n.h3,{id:"projectaddtask",children:"project.addTask()"}),"\n",(0,s.jsxs)(n.p,{children:["When you're adding an entirely new task, you'll use ",(0,s.jsx)(n.code,{children:"project.addTask()"}),". This method takes two\narguments: the name of the task, and an object with the task's configuration. The ",(0,s.jsx)(n.code,{children:"execArgs"})," property\nis the command that will be run when you run the task. The ",(0,s.jsx)(n.code,{children:"receiveArgs"})," property tells projen\nwhether to pass any arguments you provide to the task to the command. For example, if you run\n",(0,s.jsx)(n.code,{children:"pnpm projen start --port 3000"}),", projen will run ",(0,s.jsx)(n.code,{children:"ng serve --port 3000"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"projecttaskstryfindreset",children:"project.tasks.tryFind()?.reset()"}),"\n",(0,s.jsxs)(n.p,{children:["When you're modifying an existing task, you'll use ",(0,s.jsx)(n.code,{children:"project.tasks.tryFind().reset()"}),". Generally,\nyou'll want to do this when projen already has the task you're looking for defined in the\n",(0,s.jsx)(n.code,{children:".projen/tasks.json"})," file. If the task doesn't have an ",(0,s.jsx)(n.code,{children:"exec"}),"/",(0,s.jsx)(n.code,{children:"execArgs"})," parameter, you can simply reset it\nas we've done here.\nIf it does, which is the case with ",(0,s.jsx)(n.code,{children:"build"}),", it becomes more complicated. ",(0,s.jsx)(n.a,{href:"/docs/concepts/tasks/",children:"Read the docs on\ntasks"})," for more information on those cases."]}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Challenge yourself - would you use addTask() or reset() to add an ",(0,s.jsx)(n.code,{children:"ng lint"})," task?"]})}),"\n",(0,s.jsx)(n.h2,{id:"gitignore",children:"gitignore"}),"\n",(0,s.jsxs)(n.p,{children:["Projen offers a way to easily update the contents of ",(0,s.jsx)(n.code,{children:".gitignore"})," in the project definition.\nThe ",(0,s.jsx)(n.code,{children:"gitignore"}
1)," parameter takes an array of strings, each of which will be added to ",(0,s.jsx)(n.code,{children:".gitignore"}),".\nIf you'd like to simply append your ",(0,s.jsx)(n.code,{children:".gitignore.bak"})," file, split it on newlines and pass it to\n",(0,s.jsx)(n.code,{children:"gitignore"}),". Alternately, you could do a diff between ",(0,s.jsx)(n.code,{children:".gitignore"})," and ",(0,s.jsx)(n.code,{children:".gitignore.bak"})," and\nadd the new lines to ",(0,s.jsx)(n.code,{children:"gitignore"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Example:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"  gitignore: [\n    '# Compiled output',\n    '/dist',\n    '/tmp',\n    '/out-tsc',\n    '/bazel-out',\n    '',\n    '# Node',\n    '/node_modules',\n    'npm-debug.log',\n    'yarn-error.log',\n    '',\n    '# IDEs and editors',\n    '.idea/',\n    '.project',\n    '.classpath',\n    '.c9/',\n    '*.launch',\n    '.settings/',\n    '*.sublime-workspace',\n    '',\n    '# Visual Studio Code',\n    '.vscode/*',\n    '!.vscode/settings.json',\n    '!.vscode/tasks.json',\n    '!.vscode/launch.json',\n    '!.vscode/extensions.json',\n    '.history/*',\n    '',\n    '# Miscellaneous',\n    '/.angular/cache',\n    '.sass-cache/',\n    '/connect.lock',\n    '/coverage',\n    '/libpeerconnection.log',\n    'testem.log',\n    '/typings',\n    '',\n    '# System files',\n    '.DS_Store',\n    'Thumbs.db',\n  ],\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:"pnpm projen"})," and you'll see the contents of ",(0,s.jsx)(n.code,{children:".gitignore"})," have been updated."]}),"\n",(0,s.jsx)(n.h2,{id:"readmemd",children:"README.md"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"README.md"})," is not managed by projen's TypeScript project. Feel free to update it without\nworrying about projen overwriting it."]}),"\n",(0,s.jsxs)(n.p,{children:["That's it! You now have a working Angular application under projen management. Type\n",(0,s.jsx)(n.code,{children:"pnpm projen start"})," to see the application in your browser."]})]})}function p(e={}){let{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453(e,n,t){t.d(n,{R:()=>i,x:()=>o});var r=t(6540);let s={},a=r.createContext(s);function i(e){let n=r.useContext(a);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.