วิธีที่ดีที่สุดในการรวม Angular (รุ่น 2, 4, 6, ... ) สำหรับการผลิตบนเว็บเซิร์ฟเวอร์สดคืออะไร
โปรดรวมเวอร์ชันแองกูลาร์ไว้ในคำตอบเพื่อให้เราสามารถติดตามได้ดีขึ้นเมื่อมันเปลี่ยนเป็นรีลีสในภายหลัง
วิธีที่ดีที่สุดในการรวม Angular (รุ่น 2, 4, 6, ... ) สำหรับการผลิตบนเว็บเซิร์ฟเวอร์สดคืออะไร
โปรดรวมเวอร์ชันแองกูลาร์ไว้ในคำตอบเพื่อให้เราสามารถติดตามได้ดีขึ้นเมื่อมันเปลี่ยนเป็นรีลีสในภายหลัง
คำตอบ:
2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x
(TypeScript) ที่มี Angular CLInpm install -g @angular/cli
ng new projectFolder
สร้างแอปพลิเคชันใหม่ng build --prod
(ทำงานในบรรทัดคำสั่งเมื่อมีไดเรกทอรีprojectFolder
)
prod
ชุดแฟล็กสำหรับการผลิต (ดูเอกสารประกอบเชิงมุมสำหรับรายการตัวเลือกที่มาพร้อมกับแฟล็กการผลิต)
บีบอัดโดยใช้Brotli บีบอัดทรัพยากรโดยใช้คำสั่งต่อไปนี้
for i in dist/*; do brotli $i; done
บันเดิลถูกสร้างโดยค่าเริ่มต้นเป็นprojectFolder / dist (/ $ projectFolder สำหรับ 6)
ขนาดที่มี Angular 9.0.0
กับ CLI 9.0.1
และ CSS ตัวเลือกโดยไม่มีการกำหนดเส้นทาง Angular
dist/main-[es-version].[hash].js
แอปพลิเคชันของคุณรวม [ขนาด ES5: 158 KB สำหรับแอปพลิเคชัน Angular CLI ใหม่ว่างเปล่าบีบอัด40 KB ]dist/polyfill-[es-version].[hash].bundle.js
การพึ่งพา polyfill (@angular, RxJS ... ) รวมไว้ใน [ขนาด ES5: 127 KB สำหรับแอปพลิเคชัน Angular CLI ใหม่ว่างเปล่าบีบอัด37 KB ]dist/index.html
จุดเริ่มต้นของแอปพลิเคชันของคุณdist/runtime-[es-version].[hash].bundle.js
โหลด webpackdist/style.[hash].bundle.css
นิยามสไตล์dist/assets
ทรัพยากรที่คัดลอกมาจากการกำหนดค่าสินทรัพย์ Angular CLIคุณสามารถดูตัวอย่างการใช้งานของคุณโดยใช้ng serve --prod
คำสั่งที่เริ่มเซิร์ฟเวอร์ HTTP ท้องถิ่นเช่นว่าโปรแกรมที่มีไฟล์ผลิตสามารถเข้าถึงได้โดยใช้http: // localhost: 4200
สำหรับการใช้งานจริงคุณต้องปรับใช้ไฟล์ทั้งหมดจากdist
โฟลเดอร์ในเซิร์ฟเวอร์ HTTP ที่คุณเลือก
2.0.1 Final
ใช้ Gulp (TypeScript - เป้าหมาย: ES5)npm install
(ทำงานใน cmd เมื่อ direcory เป็น projectFolder)npm run bundle
(ทำงานใน cmd เมื่อ direcory เป็น projectFolder)
สร้างบันเดิลให้กับprojectFolder / bundles /
bundles/dependencies.bundle.js
[ ขนาด: ~ 1 MB (เล็กที่สุด)]
bundles/app.bundle.js
[ ขนาด: ขึ้นอยู่กับโครงการของคุณเหมืองคือ~ 0.5 MB ]
var gulp = require('gulp'),
tsc = require('gulp-typescript'),
Builder = require('systemjs-builder'),
inlineNg2Template = require('gulp-inline-ng2-template');
gulp.task('bundle', ['bundle-app', 'bundle-dependencies'], function(){});
gulp.task('inline-templates', function () {
return gulp.src('app/**/*.ts')
.pipe(inlineNg2Template({ useRelativePaths: true, indent: 0, removeLineBreaks: true}))
.pipe(tsc({
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false
}))
.pipe(gulp.dest('dist/app'));
});
gulp.task('bundle-app', ['inline-templates'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist-systemjs.config.js');
return builder
.bundle('dist/app/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'bundles/app.bundle.js', { minify: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('bundle-dependencies', ['inline-templates'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist-systemjs.config.js');
return builder
.bundle('dist/app/**/*.js - [dist/app/**/*.js]', 'bundles/dependencies.bundle.js', { minify: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
***
"gulp": "gulp",
"rimraf": "rimraf",
"bundle": "gulp bundle",
"postbundle": "rimraf dist"
},
"license": "ISC",
"dependencies": {
***
},
"devDependencies": {
"rimraf": "^2.5.2",
"gulp": "^3.9.1",
"gulp-typescript": "2.13.6",
"gulp-inline-ng2-template": "2.0.1",
"systemjs-builder": "^0.15.16"
}
}
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'app',
'rxjs': 'node_modules/rxjs',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'@angular': 'node_modules/@angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'app/boot.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }
};
var packageNames = [
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/forms',
'@angular/http',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/router',
'@angular/router-deprecated',
'@angular/testing',
'@angular/upgrade',
];
// add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
};
// filterSystemConfig - index.asp's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
var map = {
'app': 'dist/app',
};
dist-systemjs.config.js
แท็กหลังจากแท็กบันเดิลจะยังคงอนุญาตให้โปรแกรมรัน แต่บันเดิลการอ้างอิงจะถูกละเว้นและการอ้างอิงจะถูกโหลดจากnode_modules
โฟลเดอร์<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<base href="/"/>
<title>Angular</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<my-app>
loading...
</my-app>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.min.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="dist-systemjs.config.js"></script>
<!-- Project Bundles. Note that these have to be loaded AFTER the systemjs.config script -->
<script src="bundles/dependencies.bundle.js"></script>
<script src="bundles/app.bundle.js"></script>
<script>
System.import('app/boot').catch(function (err) {
console.error(err);
});
</script>
</body>
</html>
ดีที่สุดที่ฉันสามารถทำได้ :)
inline-templates
มีการเรียกใช้มัน inlines dist/app
แม่แบบแล้วสร้างสำเนาของโฟลเดอร์แอปและไฟล์ที่ จากนั้นในdist-systemjs.config.js
คุณแมปapp
ไปdist/app
ซึ่งเป็นโฟลเดอร์ที่จะไม่อยู่ถ้าคุณใช้dist
โฟลเดอร์เป็นราก คุณไม่ต้องการเรียกใช้แอพจากdist
โฟลเดอร์ใช่ไหม และถ้าเป็นเช่นนั้นคุณจะไม่มีdist
โฟลเดอร์ซ้อนอยู่ในdist
โฟลเดอร์รูท ฉันต้องคิดถึงสิ่งอื่นที่นี่ คุณไม่จำเป็นต้องบอกให้ systemjs ใช้ไฟล์บันเดิลของคุณไม่ใช่ไฟล์ปกติที่พบในdist/app
โฟลเดอร์หรือไม่?
ทีม Angular2 เผยแพร่บทช่วยสอนสำหรับการใช้ Webpack
ฉันสร้างและวางไฟล์จากการกวดวิชาในขนาดเล็กโครงการเมล็ด GitHub ดังนั้นคุณสามารถลองเวิร์กโฟลว์ได้อย่างรวดเร็ว
คำแนะนำ :
ติดตั้ง NPM
เริ่มต้นนาที สำหรับการพัฒนา สิ่งนี้จะสร้างโฟลเดอร์ "dist" เสมือนที่จะถูกนำไปโหลดที่ที่อยู่ localhost ของคุณ
NPM วิ่งสร้าง สำหรับการผลิต "นี่จะสร้างรุ่นโฟลเดอร์ทางกายภาพ" dist "เกินกว่าที่จะถูกส่งไปยังเว็บเซิร์ฟเวอร์โฟลเดอร์ dist คือ 7.8MB แต่จำเป็นต้องมีเพียง 234KB เท่านั้นในการโหลดหน้าเว็บในเว็บเบราว์เซอร์
ชุดเริ่มต้น Webpackนี้มีคุณสมบัติการทดสอบมากกว่าแบบฝึกหัดด้านบนและดูค่อนข้างเป็นที่นิยม
Angular.io มีแบบฝึกหัดเริ่มต้นอย่างรวดเร็ว ฉันคัดลอกบทช่วยสอนนี้และขยายด้วยงานอึกง่าย ๆ บางอย่างสำหรับการรวมทุกอย่างไปยังโฟลเดอร์ dist ซึ่งสามารถคัดลอกไปยังเซิร์ฟเวอร์และทำงานแบบนั้น ฉันพยายามเพิ่มประสิทธิภาพทุกอย่างเพื่อให้ทำงานได้ดีกับ Jenkis CI ดังนั้น node_modules สามารถถูกแคชและไม่จำเป็นต้องคัดลอก
ซอร์สโค้ดพร้อมแอปตัวอย่างบน Github: https://github.com/Anjmao/angular2-production-workflow
ขั้นตอนในการผลิตโหนด : ในขณะที่คุณสามารถสร้างกระบวนการสร้างของคุณเอง แต่ฉันขอแนะนำให้ใช้ angular-cli เพราะมันมีเวิร์กโฟลว์ที่จำเป็นทั้งหมดและมันทำงานได้อย่างสมบูรณ์แบบในขณะนี้ เราใช้มันในการผลิตแล้วและไม่มีปัญหาใด ๆ กับ angular-cli เลย
สิ่งนี้รองรับ:
ใหม่ชื่อโครงการ - กำลังออกเดินทาง
คุณสามารถเพิ่ม--style=scss
สำหรับการรองรับ SASS .scss
คุณสามารถเพิ่ม--ng4
การใช้ Angular 4 แทน Angular 2
หลังจากสร้างโครงการ CLI จะทำงานnpm install
ให้คุณโดยอัตโนมัติ หากคุณต้องการที่จะใช้เส้นด้ายแทนหรือเพียงแค่ต้องการที่จะมองไปที่โครงกระดูกโครงการโดยไม่ต้องติดตั้งตรวจสอบวิธีการที่จะทำมันนี่
ภายในโฟลเดอร์โครงการ:
ng build -prod
ในเวอร์ชันปัจจุบันคุณต้องระบุ--aot
ด้วยตนเองเพราะสามารถใช้ในโหมดการพัฒนา (แม้ว่าจะไม่สามารถใช้งานได้จริงเนื่องจากความช้า)
สิ่งนี้ยังทำการคอมไพล์ AoT สำหรับบันเดิลขนาดเล็กลง (ไม่มี Angular compiler แทนสร้างคอมไพเลอร์เอาท์พุท) บันเดิลนั้นเล็กกว่า AoT มากถ้าคุณใช้ Angular 4 เนื่องจากโค้ดที่สร้างนั้นมีขนาดเล็กกว่า
คุณสามารถทดสอบแอปของคุณกับทอทโหมดการพัฒนา (sourcemaps ไม่มี minification) ng build --aot
ทอทโดยการเรียกใช้
dir เอาท์พุทเริ่มต้นคือ./dist
แม้ว่ามันสามารถเปลี่ยนแปลง./angular-cli.json
ได้
ผลลัพธ์ของขั้นตอนการสร้างมีดังต่อไปนี้:
(หมายเหตุ: <content-hash>
หมายถึงแฮช / ลายนิ้วมือของเนื้อหาของไฟล์ที่มีความหมายว่าเป็นวิธีการป้องกันแคชซึ่งเป็นไปได้เนื่องจาก Webpack เขียนscript
แท็กด้วยตัวเอง)
./dist/assets
./src/assets/**
./dist/index.html
./src/index.html
, หลังจากเพิ่มสคริปต์ webpack ลงใน./angular-cli.json
./dist/inline.js
./dist/main.<content-hash>.bundle.js
./dist/styles.<content-hash>.bundle.js
ในรุ่นก่อนหน้านี้มันยังสร้าง gzipped รุ่นสำหรับตรวจสอบขนาดและ.map
ไฟล์ซอร์สแผนที่ แต่สิ่งนี้ไม่ได้เกิดขึ้นอีกต่อไปเมื่อมีคนขอให้ลบไฟล์เหล่านี้
ในบางโอกาสคุณอาจพบไฟล์ / โฟลเดอร์ที่ไม่ต้องการอื่น ๆ :
./out-tsc/
./src/tsconfig.json
'soutDir
./out-tsc-e2e/
./e2e/tsconfig.json
'soutDir
./dist/ngfactory/
<content-hash>
จากกลุ่มในแยง มันอาจทำให้เกิดปัญหาในการรับชุดล่าสุด?
ณ วันนี้ฉันยังคงพบตำราปรุงอาหารล่วงหน้าเวลาเป็นสูตรที่ดีที่สุดสำหรับการผลิตรวม คุณสามารถค้นหาได้ที่นี่: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
ประสบการณ์ของฉันกับ Angular 2 จนถึงขณะนี้คือ AoT สร้างงานสร้างที่เล็กที่สุดโดยแทบไม่มีเวลาโหลด และที่สำคัญที่สุดคือคำถามที่นี่เป็นเรื่องเกี่ยวกับ - คุณจะต้องจัดส่งไฟล์ไม่กี่ไฟล์เพื่อการผลิต
สิ่งนี้น่าจะเป็นเพราะคอมไพเลอร์ Angular จะไม่ถูกส่งมาพร้อมกับบิลด์โปรดักชั่นเนื่องจากเทมเพลตจะถูกคอมไพล์ "Ahead of Time" นอกจากนี้ยังเป็นเรื่องที่ยอดเยี่ยมมากเมื่อเห็นว่ามาร์กอัป HTML เทมเพลตของคุณเปลี่ยนเป็นคำสั่ง javascript ซึ่งยากที่จะแปลงวิศวกรกลับเป็น HTML ดั้งเดิม
ฉันสร้างวิดีโออย่างง่ายที่แสดงขนาดการดาวน์โหลดจำนวนไฟล์และอื่น ๆ สำหรับแอพ Angular 2 ใน dev vs AoT build ซึ่งคุณสามารถดูได้ที่นี่:
คุณจะพบซอร์สโค้ดที่ใช้ในวิดีโอที่นี่:
**Production build with
- Angular Rc5
- Gulp
- typescripts
- systemjs**
1)con-cat all js files and css files include on index.html using "gulp-concat".
- styles.css (all css concat in this files)
- shims.js(all js concat in this files)
2)copy all images and fonts as well as html files with gulp task to "/dist".
3)Bundling -minify angular libraries and app components mentioned in systemjs.config.js file.
Using gulp 'systemjs-builder'
SystemBuilder = require('systemjs-builder'),
gulp.task('system-build', ['tsc'], function () {
var builder = new SystemBuilder();
return builder.loadConfig('systemjs.config.js')
.then(function () {
builder.buildStatic('assets', 'dist/app/app_libs_bundle.js')
})
.then(function () {
del('temp')
})
});
4)Minify bundles using 'gulp-uglify'
jsMinify = require('gulp-uglify'),
gulp.task('minify', function () {
var options = {
mangle: false
};
var js = gulp.src('dist/app/shims.js')
.pipe(jsMinify())
.pipe(gulp.dest('dist/app/'));
var js1 = gulp.src('dist/app/app_libs_bundle.js')
.pipe(jsMinify(options))
.pipe(gulp.dest('dist/app/'));
var css = gulp.src('dist/css/styles.min.css');
return merge(js,js1, css);
});
5) In index.html for production
<html>
<head>
<title>Hello</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<link rel="stylesheet" href="app/css/styles.min.css" />
<script type="text/javascript" src="app/shims.js"></script>
<base href="https://stackoverflow.com/">
</head>
<body>
<my-app>Loading...</my-app>
<script type="text/javascript" src="app/app_libs_bundle.js"></script>
</body>
</html>
6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www.
คุณสามารถปรับใช้แอปพลิเคชันเชิงมุมของคุณgithub
โดยใช้
angular-cli-ghpages
ตรวจสอบลิงค์เพื่อค้นหาวิธีการปรับใช้โดยใช้ CLI นี้
เว็บไซต์ที่ใช้งานจะถูกเก็บไว้ในสาขาบางแห่งgithub
โดยทั่วไป
GH-หน้า
ใช้สามารถโคลนสาขา git และใช้มันเหมือนเว็บไซต์คงที่ในเซิร์ฟเวอร์ของคุณ
"ดีที่สุด" ขึ้นอยู่กับสถานการณ์ มีบางครั้งที่คุณสนใจเพียงกลุ่มเดียวที่เล็กที่สุดเท่าที่จะเป็นไปได้ แต่ในแอพขนาดใหญ่คุณอาจต้องพิจารณาการโหลดที่ขี้เกียจ ในบางจุดการใช้งานทั้งแอปเป็นชุดเดียวไม่สามารถทำได้
ในกรณีหลัง Webpack เป็นวิธีที่ดีที่สุดเพราะรองรับการแยกรหัส
สำหรับกลุ่มเดียวฉันจะพิจารณา Rollup หรือคอมไพเลอร์ปิดหากคุณรู้สึกกล้า :-)
ฉันสร้างตัวอย่างของตัวรวบรวมเชิงมุมทั้งหมดที่ฉันเคยใช้ที่นี่: http://www.syntaxsuccess.com/viewarticle/angular-production-builds
รหัสสามารถพบได้ที่นี่: https://github.com/thelgevold/angular-2-samples
เวอร์ชั่นเชิงมุม: 4.1.x
เพียงแค่ติดตั้งเชิงมุม 4 ด้วย webpack 3 ภายในไม่กี่นาทีการพัฒนาและการผลิตชุด ENV ของคุณจะพร้อมโดยไม่มีปัญหาใด ๆ เพียงแค่ทำตามขั้นตอนด้านล่าง github doc
โปรดลองคำสั่ง CLI ด้านล่างในไดเรกทอรีโครงการปัจจุบัน มันจะสร้างมัดโฟลเดอร์ dist เพื่อให้คุณสามารถอัปโหลดไฟล์ทั้งหมดภายในโฟลเดอร์ dist สำหรับการปรับใช้
ng build --prod --aot --base-href
ng ให้บริการงานสำหรับการให้บริการแอปพลิเคชันของเราเพื่อการพัฒนา แล้วการผลิตล่ะ? หากเราดูไฟล์ package.json ของเราเราจะเห็นว่ามีสคริปต์ที่เราสามารถใช้ได้:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
สคริปต์การสร้างใช้การสร้าง ng ของ Angular CLI ด้วยแฟล็ก --prod ลองตอนนี้กัน เราสามารถทำได้หนึ่งในสองวิธี:
# ใช้สคริปต์ npm
npm run build
# ใช้ cli โดยตรง
ng build --prod
เวลานี้เราได้รับสี่ไฟล์แทนที่จะเป็นห้าไฟล์ ธง --prod บอกให้ Angular ทำให้แอปพลิเคชันของเรามีขนาดเล็กลงมาก