引言
AngularJS(通常指Angular 1.x版本)作为一个成熟的前端MVC框架,虽然现在已经有了更现代的替代品(如Angular 2+、React、Vue等),但在许多遗留项目中仍然广泛使用。正确部署AngularJS项目对于确保应用性能、安全性和用户体验至关重要。本文将详细介绍AngularJS项目从开发环境搭建到生产环境配置的完整流程,并提供常见问题的解决方案和优化技巧。
一、开发环境搭建
1.1 安装Node.js和npm
AngularJS项目通常需要Node.js和npm(Node Package Manager)来管理依赖包。虽然AngularJS本身不直接依赖Node.js,但现代开发流程中,我们通常使用npm来安装工具如Bower、Gulp或Grunt等。
步骤:
访问
Node.js官网
下载并安装LTS版本(推荐)。
安装完成后,打开终端或命令提示符,运行以下命令验证安装:
node -v
npm -v
这将显示安装的Node.js和npm版本。
1.2 安装Bower(可选但推荐)
虽然npm现在可以管理前端依赖,但AngularJS项目早期通常使用Bower。如果你的项目使用Bower,需要先安装它。
安装Bower:
npm install -g bower
验证安装:
bower -v
1.3 初始化项目
创建一个新目录作为项目根目录,并初始化npm和Bower(如果使用)。
步骤:
创建项目目录并进入:
mkdir my-angularjs-app
cd my-angularjs-app
初始化npm(生成
package.json
文件):
npm init -y
初始化Bower(如果使用,生成
bower.json
文件):
bower init
1.4 安装AngularJS及相关依赖
使用npm安装AngularJS:
npm install angular
使用Bower安装AngularJS:
bower install angular
安装其他常用依赖(如Angular路由):
npm install angular-route
# 或
bower install angular-route
1.5 创建基本项目结构
一个典型的AngularJS项目结构如下:
my-angularjs-app/
├── app/
│ ├── index.html
│ ├── scripts/
│ │ ├── app.js
│ │ ├── controllers/
│ │ │ └── mainController.js
│ │ └── services/
│ ├── styles/
│ │ └── main.css
│ └── views/
│ └── main.html
├── node_modules/ (npm安装的依赖)
├── bower_components/ (Bower安装的依赖,如果使用)
├── package.json
├── bower.json (如果使用Bower)
└── .gitignore
创建入口文件
app/index.html
:
{{ mainCtrl.message }}
创建主应用模块
app/scripts/app.js
:
‘use strict’;
// 定义AngularJS应用模块
angular.module(‘myApp’, [‘ngRoute’])
.config([‘$routeProvider’, function($routeProvider) {
$routeProvider
.when(‘/’, {
templateUrl: ‘views/main.html’,
controller: ‘MainController’,
controllerAs: ‘mainCtrl’
})
.otherwise({
redirectTo: ‘/’
});
}]);
创建控制器
app/scripts/controllers/mainController.js
:
‘use strict’;
angular.module(‘myApp’)
.controller(‘MainController’, function() {
this.message = ‘Hello from AngularJS!’;
});
创建视图
app/views/main.html
:
This is the main view.
创建样式
app/styles/main.css
:
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
color: #333;
}
1.6 安装开发工具(可选但推荐)
1.6.1 安装本地服务器(如http-server)
为了在本地运行和测试应用,可以安装一个简单的HTTP服务器。
npm install -g http-server
运行应用:
在项目根目录下运行:
http-server app
然后在浏览器中访问
http://localhost:8080
。
1.6.2 安装构建工具(如Gulp或Grunt)
虽然AngularJS项目可以手动管理,但使用构建工具可以自动化任务如代码压缩、合并、测试等。这里以Gulp为例。
安装Gulp:
npm install –save-dev gulp
全局安装Gulp CLI:
npm install -g gulp-cli
创建
gulpfile.js
:
const gulp = require(‘gulp’);
const uglify = require(‘gulp-uglify’);
const concat = require(‘gulp-concat’);
const cleanCSS = require(‘gulp-clean-css’);
const htmlmin = require(‘gulp-htmlmin’);
// 复制HTML文件
gulp.task(‘copy-html’, function() {
return gulp.src(‘app/**/*.html’)
.pipe(gulp.dest(‘dist’));
});
// 压缩JavaScript
gulp.task(‘scripts’, function() {
return gulp.src(‘app/scripts/**/*.js’)
.pipe(concat(‘all.js’))
.pipe(uglify())
.pipe(gulp.dest(‘dist/scripts’));
});
// 压缩CSS
gulp.task(‘styles’, function() {
return gulp.src(‘app/styles/**/*.css’)
.pipe(cleanCSS())
.pipe(gulp.dest(‘dist/styles’));
});
// 压缩HTML
gulp.task(‘html’, function() {
return gulp.src(‘dist/**/*.html’)
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest(‘dist’));
});
// 默认任务
gulp.task(‘default’, gulp.series(‘copy-html’, ‘scripts’, ‘styles’, ‘html’));
安装Gulp插件:
npm install –save-dev gulp-uglify gulp-concat gulp-clean-css gulp-htmlmin
运行构建:
gulp
这将生成一个
dist
目录,包含优化后的代码。
二、开发环境配置
2.1 版本控制(Git)
使用Git进行版本控制是开发的基本要求。
初始化Git仓库:
git init
创建
.gitignore
文件:
# 忽略Node.js依赖
node_modules/
# 忽略Bower依赖(如果使用)
bower_components/
# 忽略构建输出
dist/
build/
# 忽略环境变量文件
.env
# 忽略日志文件
*.log
# 忽略系统文件
.DS_Store
Thumbs.db
提交初始代码:
git add .
git commit -m “Initial commit”
2.2 代码质量工具
2.2.1 ESLint
安装ESLint来检查JavaScript代码质量。
npm install –save-dev eslint eslint-config-angular eslint-plugin-angular
创建
.eslintrc.json
:
{
“extends”: “angular”,
“env”: {
“browser”: true,
“jasmine”: true
},
“rules”: {
“no-console”: “off”
}
}
运行ESLint:
npx eslint app/scripts/
2.2.2 JSHint(可选)
另一个流行的JavaScript代码质量工具。
npm install –save-dev jshint
创建
.jshintrc
:
{
“asi”: false,
“browser”: true,
“curly”: true,
“eqeqeq”: true,
“eqnull”: true,
“expr”: true,
“immed”: true,
“newcap”: true,
“noarg”: true,
“smarttabs”: true,
“sub”: true,
“undef”: true,
“unused”: true
}
2.3 自动化测试
2.3.1 安装Karma和Jasmine
Karma是测试运行器,Jasmine是测试框架。
npm install –save-dev karma karma-jasmine karma-chrome-launcher karma-coverage
初始化Karma:
npx karma init
选择Jasmine作为框架,Chrome作为浏览器,然后生成
karma.conf.js
。
配置
karma.conf.js
(部分):
module.exports = function(config) {
config.set({
basePath: ”,
frameworks: [‘jasmine’],
files: [
‘node_modules/angular/angular.js’,
‘node_modules/angular-route/angular-route.js’,
‘node_modules/angular-mocks/angular-mocks.js’,
‘app/scripts/**/*.js’,
‘test/**/*.spec.js’
],
exclude: [],
preprocessors: {
‘app/scripts/**/*.js’: [‘coverage’]
},
reporters: [‘progress’, ‘coverage’],
coverageReporter: {
type: ‘html’,
dir: ‘coverage/’
},
browsers: [‘Chrome’],
singleRun: true
});
};
创建测试文件
test/mainController.spec.js
:
describe(‘MainController’, function() {
var $controller, $scope;
beforeEach(module(‘myApp’));
beforeEach(inject(function(_$controller_, $rootScope) {
$scope = $rootScope.$new();
$controller = _$controller_(‘MainController’, { $scope: $scope });
}));
it(‘should have a message’, function() {
expect($scope.mainCtrl.message).toBe(‘Hello from AngularJS!’);
});
});
运行测试:
npx karma start
2.4 开发服务器配置
2.4.1 使用BrowserSync(可选)
BrowserSync可以提供实时重载功能。
npm install –save-dev browser-sync
创建
gulpfile.js
中的BrowserSync任务:
const browserSync = require(‘browser-sync’);
gulp.task(‘serve’, function() {
browserSync.init({
server: {
baseDir: ‘./app’
}
});
gulp.watch(‘app/**/*.html’).on(‘change’, browserSync.reload);
gulp.watch(‘app/scripts/**/*.js’).on(‘change’, browserSync.reload);
gulp.watch(‘app/styles/**/*.css’).on(‘change’, browserSync.reload);
});
gulp.task(‘default’, gulp.series(‘copy-html’, ‘scripts’, ‘styles’, ‘html’, ‘serve’));
运行开发服务器:
gulp serve
三、生产环境配置
3.1 构建生产版本
3.1.1 使用Gulp构建
前面已经创建了基本的Gulp任务,现在可以扩展它以生成生产版本。
扩展
gulpfile.js
:
const del = require(‘del’);
const runSequence = require(‘run-sequence’);
// 清理dist目录
gulp.task(‘clean’, function() {
return del([‘dist/**/*’]);
});
// 复制字体文件(如果有)
gulp.task(‘fonts’, function() {
return gulp.src(‘app/fonts/**/*’)
.pipe(gulp.dest(‘dist/fonts’));
});
// 复制图片(如果有)
gulp.task(‘images’, function() {
return gulp.src(‘app/images/**/*’)
.pipe(gulp.dest(‘dist/images’));
});
// 构建任务
gulp.task(‘build’, function(callback) {
runSequence(
‘clean’,
[‘copy-html’, ‘scripts’, ‘styles’, ‘fonts’, ‘images’],
‘html’,
callback
);
});
运行构建:
gulp build
3.1.2 使用Webpack(现代方法)
虽然AngularJS项目通常使用Gulp/Grunt,但也可以使用Webpack进行构建。
安装Webpack及相关插件:
npm install –save-dev webpack webpack-cli webpack-dev-server
npm install –save-dev babel-loader @babel/core @babel/preset-env
npm install –save-dev html-webpack-plugin css-loader style-loader
创建
webpack.config.js
:
const path = require(‘path’);
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
module.exports = {
entry: ‘./app/scripts/app.js’,
output: {
path: path.resolve(__dirname, ‘dist’),
filename: ‘bundle.js’
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: ‘babel-loader’,
options: {
presets: [‘@babel/preset-env’]
}
}
},
{
test: /\.css$/,
use: [‘style-loader’, ‘css-loader’]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: ‘./app/index.html’,
filename: ‘index.html’
})
],
devServer: {
contentBase: path.join(__dirname, ‘dist’),
compress: true,
port: 9000
}
};
修改
app/index.html
以适应Webpack:
{{ mainCtrl.message }}
修改
app/scripts/app.js
以包含CSS:
‘use strict’;
// 引入CSS
require(‘../styles/main.css’);
// 定义AngularJS应用模块
angular.module(‘myApp’, [‘ngRoute’])
.config([‘$routeProvider’, function($routeProvider) {
$routeProvider
.when(‘/’, {
templateUrl: ‘views/main.html’,
controller: ‘MainController’,
controllerAs: ‘mainCtrl’
})
.otherwise({
redirectTo: ‘/’
});
}]);
运行Webpack开发服务器:
npx webpack serve
构建生产版本:
npx webpack –mode production
3.2 服务器配置
3.2.1 Nginx配置
Nginx是一个高性能的HTTP服务器,常用于生产环境。
安装Nginx:
# Ubuntu/Debian
sudo apt-get install nginx
# CentOS/RHEL
sudo yum install nginx
配置Nginx(示例):
创建
/etc/nginx/sites-available/my-angularjs-app
:
server {
listen 80;
server_name example.com www.example.com;
root /path/to/your/dist;
index index.html;
# 启用Gzip压缩
gzip on;
gzip_types text/plain text/css application/javascript application/json text/xml application/xml application/xml+rss text/javascript;
# 处理AngularJS的HTML5模式
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control “public, immutable”;
}
# 安全头
add_header X-Frame-Options “SAMEORIGIN”;
add_header X-Content-Type-Options “nosniff”;
add_header X-XSS-Protection “1; mode=block”;
# 限制请求大小
client_max_body_size 10M;
# 代理API请求(如果有后端)
location /api/ {
proxy_pass http://backend-server:port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
启用站点:
sudo ln -s /etc/nginx/sites-available/my-angularjs-app /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置
sudo systemctl reload nginx
3.2.2 Apache配置
如果使用Apache服务器:
安装Apache:
# Ubuntu/Debian
sudo apt-get install apache2
# CentOS/RHEL
sudo yum install httpd
配置虚拟主机(示例):
创建
/etc/apache2/sites-available/my-angularjs-app.conf
:
ServerName example.com
ServerAlias www.example.com
DocumentRoot /path/to/your/dist
# 启用mod_rewrite
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# 启用Gzip压缩
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
# 处理AngularJS的HTML5模式
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
# 静态资源缓存
Header set Cache-Control “max-age=31536000, public”
# 安全头
Header always set X-Frame-Options “SAMEORIGIN”
Header always set X-Content-Type-Options “nosniff”
Header always set X-XSS-Protection “1; mode=block”
启用站点:
sudo a2ensite my-angularjs-app
sudo systemctl reload apache2
3.3 HTTPS配置
3.3.1 使用Let’s Encrypt获取免费SSL证书
安装Certbot:
# Ubuntu/Debian
sudo apt-get install certbot python3-certbot-nginx
# CentOS/RHEL
sudo yum install certbot python3-certbot-nginx
获取并安装证书:
sudo certbot –nginx -d example.com -d www.example.com
自动续期:
Certbot会自动设置cron任务,但可以手动测试:
sudo certbot renew –dry-run
3.4 环境变量管理
在AngularJS中,通常使用常量服务来管理环境变量。
创建环境配置服务
app/scripts/services/config.js
:
‘use strict’;
angular.module(‘myApp’)
.constant(‘Config’, {
API_URL: ‘https://api.example.com’,
DEBUG: false,
VERSION: ‘1.0.0’
});
在控制器中使用:
‘use strict’;
angular.module(‘myApp’)
.controller(‘MainController’, function(Config) {
this.message = ‘Hello from AngularJS!’;
this.apiUrl = Config.API_URL;
});
对于不同环境,可以使用构建过程替换配置:
使用Gulp替换环境变量:
const replace = require(‘gulp-replace’);
const argv = require(‘yargs’).argv;
gulp.task(‘config’, function() {
const env = argv.env || ‘development’;
const config = {
development: {
API_URL: ‘http://localhost:3000’,
DEBUG: true
},
production: {
API_URL: ‘https://api.example.com’,
DEBUG: false
}
};
return gulp.src(‘dist/scripts/services/config.js’)
.pipe(replace(/API_URL:\s*[‘”][^’”]+[‘”]/, `API_URL: ‘${config[env].API_URL}’`))
.pipe(replace(/DEBUG:\s*(true|false)/, `DEBUG: ${config[env].DEBUG}`))
.pipe(gulp.dest(‘dist/scripts/services’));
});
构建时指定环境:
gulp build –env=production
四、常见部署问题与解决方案
4.1 路由问题(HTML5模式)
问题描述:
在AngularJS中使用HTML5模式(
$locationProvider.html5Mode(true)
)时,直接访问子路由或刷新页面会导致404错误。
解决方案:
服务器端配置
:确保服务器配置了重写规则,将所有非静态文件请求重定向到
index.html
。
Nginx配置:
location / {
try_files $uri $uri/ /index.html;
}
Apache配置:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
设置
标签
:
在
index.html
的
中添加:
配置
$locationProvider
:
angular.module(‘myApp’)
.config([‘$locationProvider’, function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
}]);
4.2 跨域问题(CORS)
问题描述:
前端应用与后端API不在同一个域时,浏览器会阻止请求。
解决方案:
后端配置CORS头
:
在后端服务器响应中添加:
Access-Control-Allow-Origin: https://your-frontend-domain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
使用代理
:
在开发环境中,可以使用代理避免CORS:
Webpack Dev Server代理:
devServer: {
proxy: {
‘/api’: {
target: ‘http://localhost:3000’,
changeOrigin: true,
pathRewrite: {‘^/api’: ”}
}
}
}
Gulp BrowserSync代理:
browserSync.init({
server: {
baseDir: ‘./app’
},
proxy: ‘http://localhost:3000’,
port: 3000
});
JSONP(仅限GET请求)
:
angular.module(‘myApp’)
.controller(‘MainController’, function($http) {
$http.jsonp(‘http://example.com/api?callback=JSON_CALLBACK’)
.then(function(response) {
console.log(response.data);
});
});
4.3 性能优化问题
问题描述:
应用加载慢、内存泄漏、响应不及时。
解决方案:
4.3.1 代码分割与懒加载
使用
ocLazyLoad
(AngularJS懒加载模块):
安装:
npm install oclazyload
配置:
angular.module(‘myApp’, [‘oc.lazyLoad’])
.config([‘$ocLazyLoadProvider’, function($ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
debug: false,
events: true
});
}])
.controller(‘MainController’, function($ocLazyLoad, $state) {
// 懒加载模块
$ocLazyLoad.load(‘scripts/lazyModule.js’).then(function() {
// 模块加载完成后的逻辑
});
});
4.3.2 减少 watchers 数量
问题:
AngularJS的双向绑定依赖于 watchers,过多的 watchers 会严重影响性能。
解决方案:
使用单次绑定(
::
)
:
避免在模板中使用复杂表达式
:
“`javascript
// 不推荐
{{ calculateTotal() }}
// 推荐:在控制器中计算
$scope.total = calculateTotal();
{{ total }}
3. **使用 `track by` 提高 `ng-repeat` 性能**:
“`html
限制
$digest
循环
:
// 使用 $watch 替代 $scope.$apply
$scope.$watch(‘someVar’, function(newVal, oldVal) {
if (newVal !== oldVal) {
// 只在需要时触发更新
}
});
4.3.3 内存泄漏预防
常见原因:
未取消的事件监听器
未销毁的定时器
未清理的 DOM 事件
解决方案:
在
$destroy
事件中清理
:
angular.module(‘myApp’)
.controller(‘MainController’, function($scope, $interval) {
var timer = $interval(function() {
// 定时任务
}, 1000);
$scope.$on(‘$destroy’, function() {
$interval.cancel(timer);
// 清理其他资源
});
});
使用
$rootScope
谨慎
:
避免在
$rootScope
上绑定大量数据。
使用
one-time binding
:
如前所述,使用
::
减少不必要的 watchers。
4.4 安全问题
4.4.1 XSS(跨站脚本攻击)
解决方案:
使用 AngularJS 的内置转义
:
AngularJS 默认会转义插值表达式中的内容。
使用
ng-bind-html
需要
$sce
严格上下文转义
:
angular.module(‘myApp’)
.controller(‘MainController’, function($sce, $scope) {
$scope.trustedHtml = $sce.trustAsHtml(‘安全HTML‘);
});
避免使用
ng-bind-html
处理用户输入
:
除非明确需要,否则不要将用户输入作为HTML渲染。
4.4.2 CSRF(跨站请求伪造)
解决方案:
使用 CSRF Token
:
angular.module(‘myApp’)
.config([‘$httpProvider’, function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = ‘XSRF-TOKEN’;
$httpProvider.defaults.xsrfHeaderName = ‘X-XSRF-TOKEN’;
}]);
后端验证 Token
:
确保后端验证每个请求中的 CSRF Token。
4.4.3 敏感数据暴露
解决方案:
不要在客户端存储敏感信息
:
避免在 localStorage 或 sessionStorage 中存储 token、密码等。
使用 HTTP Only Cookies
:
对于 session token,使用 HTTP Only cookies。
环境配置分离
:
确保生产环境的 API 密钥、端点等与开发环境分离。
4.5 构建与部署自动化
4.5.1 使用 CI/CD 工具
示例:GitHub Actions
创建
.github/workflows/deploy.yml
:
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v2
– name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: ’14’
– name: Install dependencies
run: npm ci
– name: Run tests
run: npm test
– name: Build
run: npm run build
– name: Deploy to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
source: “dist/”
target: “/var/www/my-angularjs-app”
4.5.2 Docker 化部署
创建
Dockerfile
:
# 构建阶段
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
# 复制构建产物
COPY –from=builder /app/dist /usr/share/nginx/html
# 复制Nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD [“nginx”, “-g”, “daemon off;”]
创建
nginx.conf
:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Gzip压缩
gzip on;
gzip_types text/plain text/css application/javascript application/json text/xml application/xml application/xml+rss text/javascript;
}
构建和运行:
docker build -t my-angularjs-app .
docker run -p 8080:80 my-angularjs-app
五、优化技巧
5.1 代码优化
5.1.1 使用 Babel 转译
确保代码兼容旧浏览器。
安装 Babel:
npm install –save-dev @babel/core @babel/preset-env babel-loader
配置
.babelrc
:
{
“presets”: [“@babel/preset-env”]
}
在 Webpack 中使用:
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: ‘babel-loader’
}
}
]
}
5.1.2 依赖管理
使用
npm ci
而非
npm install
:
在 CI/CD 中,使用
npm ci
可以确保安装的依赖版本与
package-lock.json
完全一致。
5.2 资源优化
5.2.1 图片优化
使用
gulp-imagemin
:
npm install –save-dev gulp-imagemin
添加 Gulp 任务:
const imagemin = require(‘gulp-imagemin’);
gulp.task(‘images’, function() {
return gulp.src(‘app/images/**/*’)
.pipe(imagemin())
.pipe(gulp.dest(‘dist/images’));
});
5.2.2 字体优化
使用
gulp-fontmin
(如果需要):
npm install –save-dev gulp-fontmin
5.3 缓存策略
5.3.1 浏览器缓存
Nginx 配置:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 1y;
add_header Cache-Control “public, immutable”;
}
5.3.2 Service Worker(高级)
安装
sw-precache
:
npm install –save-dev sw-precache
创建 Gulp 任务:
const swPrecache = require(‘sw-precache’);
gulp.task(‘service-worker’, function(callback) {
swPrecache.write(‘dist/service-worker.js’, {
staticFileGlobs: [‘dist/**/*.{html,css,js,png,jpg,gif,svg,woff,woff2,ttf}’],
stripPrefix: ‘dist’,
runtimeCaching: [{
urlPattern: /^https:\/\/api\.example\.com/,
handler: ‘networkFirst’
}]
}, callback);
});
5.4 监控与日志
5.4.1 错误监控
使用 Sentry(示例):
安装:
npm install @sentry/browser
初始化:
“`javascript
import * as Sentry from ‘@sentry/browser’;
Sentry.init({
dsn: ‘https://your-dsn@sentry.io/project-id’,
environment: ‘production’
});
// 在AngularJS中使用
angular.module(‘myApp’)
.config([‘$provide’, function($provide) {
$provide.decorator(‘$exceptionHandler’, function($delegate) {
return function(exception, cause) {
Sentry.captureException(exception);
$delegate(exception, cause);
};
});
}]);
#### 5.4.2 性能监控
**使用 `performance.mark` 和 `performance.measure`:**
“`javascript
// 在关键代码处标记
performance.mark(‘start-operation’);
// … 执行操作
performance.mark(‘end-operation’);
performance.measure(‘operation-duration’, ‘start-operation’, ‘end-operation’);
// 获取测量结果
const measures = performance.getEntriesByName(‘operation-duration’);
console.log(‘Duration:’, measures[0].duration);
六、总结
AngularJS项目的部署是一个涉及多个环节的复杂过程,从开发环境的搭建到生产环境的配置,每一步都需要仔细规划和执行。通过本文的详细指南,你应该能够:
正确搭建开发环境
:包括Node.js、npm、Bower、Gulp等工具的安装和配置。
配置开发环境
:包括版本控制、代码质量工具、自动化测试和开发服务器。
构建生产版本
:使用Gulp或Webpack进行代码优化和打包。
配置生产服务器
:使用Nginx或Apache,并启用HTTPS。
解决常见问题
:如路由问题、跨域问题、性能问题和安全问题。
应用优化技巧
:包括代码优化、资源优化、缓存策略和监控。
记住,虽然AngularJS是一个较老的框架,但通过现代工具和最佳实践,仍然可以构建和部署高性能、安全的应用。随着技术的不断发展,建议逐步迁移到更现代的框架,如Angular 2+、React或Vue,以获得更好的开发体验和性能。
附录:常用命令速查表
任务
命令
安装依赖
npm install
或
bower install
运行开发服务器
http-server app
或
gulp serve
运行测试
npx karma start
构建生产版本
gulp build
或
npm run build
运行ESLint
npx eslint app/scripts/
运行Docker构建
docker build -t my-app .
运行Docker容器
docker run -p 8080:80 my-app
通过遵循这些步骤和最佳实践,你可以确保你的AngularJS项目在生产环境中稳定、高效地运行。
# AngularJS项目部署全流程详解:从开发环境搭建到生产环境配置的完整指南
引言
AngularJS(通常指Angular 1.x版本)作为一个成熟的前端MVC框架,虽然现在已经有了更现代的替代品(如Angular 2+、React、Vue等),但在许多遗留项目中仍然广泛使用。正确部署AngularJS项目对于确保应用性能、安全性和用户体验至关重要。本文将详细介绍AngularJS项目从开发环境搭建到生产环境配置的完整流程,并提供常见问题的解决方案和优化技巧。
一、开发环境搭建
1.1 安装Node.js和npm
AngularJS项目通常需要Node.js和npm(Node Package Manager)来管理依赖包。虽然AngularJS本身不直接依赖Node.js,但现代开发流程中,我们通常使用npm来安装工具如Bower、Gulp或Grunt等。
步骤:
访问
Node.js官网
下载并安装LTS版本(推荐)。
安装完成后,打开终端或命令提示符,运行以下命令验证安装:
node -v
npm -v
这将显示安装的Node.js和npm版本。
1.2 安装Bower(可选但推荐)
虽然npm现在可以管理前端依赖,但AngularJS项目早期通常使用Bower。如果你的项目使用Bower,需要先安装它。
安装Bower:
npm install -g bower
验证安装:
bower -v
1.3 初始化项目
创建一个新目录作为项目根目录,并初始化npm和Bower(如果使用)。
步骤:
创建项目目录并进入:
mkdir my-angularjs-app
cd my-angularjs-app
初始化npm(生成
package.json
文件):
npm init -y
初始化Bower(如果使用,生成
bower.json
文件):
bower init
1.4 安装AngularJS及相关依赖
使用npm安装AngularJS:
npm install angular
使用Bower安装AngularJS:
bower install angular
安装其他常用依赖(如Angular路由):
npm install angular-route
# 或
bower install angular-route
1.5 创建基本项目结构
一个典型的AngularJS项目结构如下:
my-angularjs-app/
├── app/
│ ├── index.html
│ ├── scripts/
│ │ ├── app.js
│ │ ├── controllers/
│ │ │ └── mainController.js
│ │ └── services/
│ ├── styles/
│ │ └── main.css
│ └── views/
│ └── main.html
├── node_modules/ (npm安装的依赖)
├── bower_components/ (Bower安装的依赖,如果使用)
├── package.json
├── bower.json (如果使用Bower)
└── .gitignore
创建入口文件
app/index.html
:
{{ mainCtrl.message }}
创建主应用模块
app/scripts/app.js
:
‘use strict’;
// 定义AngularJS应用模块
angular.module(‘myApp’, [‘ngRoute’])
.config([‘$routeProvider’, function($routeProvider) {
$routeProvider
.when(‘/’, {
templateUrl: ‘views/main.html’,
controller: ‘MainController’,
controllerAs: ‘mainCtrl’
})
.otherwise({
redirectTo: ‘/’
});
}]);
创建控制器
app/scripts/controllers/mainController.js
:
‘use strict’;
angular.module(‘myApp’)
.controller(‘MainController’, function() {
this.message = ‘Hello from AngularJS!’;
});
创建视图
app/views/main.html
:
This is the main view.
创建样式
app/styles/main.css
:
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
color: #333;
}
1.6 安装开发工具(可选但推荐)
1.6.1 安装本地服务器(如http-server)
为了在本地运行和测试应用,可以安装一个简单的HTTP服务器。
npm install -g http-server
运行应用:
在项目根目录下运行:
http-server app
然后在浏览器中访问
http://localhost:8080
。
1.6.2 安装构建工具(如Gulp或Grunt)
虽然AngularJS项目可以手动管理,但使用构建工具可以自动化任务如代码压缩、合并、测试等。这里以Gulp为例。
安装Gulp:
npm install –save-dev gulp
全局安装Gulp CLI:
npm install -g gulp-cli
创建
gulpfile.js
:
const gulp = require(‘gulp’);
const uglify = require(‘gulp-uglify’);
const concat = require(‘gulp-concat’);
const cleanCSS = require(‘gulp-clean-css’);
const htmlmin = require(‘gulp-htmlmin’);
// 复制HTML文件
gulp.task(‘copy-html’, function() {
return gulp.src(‘app/**/*.html’)
.pipe(gulp.dest(‘dist’));
});
// 压缩JavaScript
gulp.task(‘scripts’, function() {
return gulp.src(‘app/scripts/**/*.js’)
.pipe(concat(‘all.js’))
.pipe(uglify())
.pipe(gulp.dest(‘dist/scripts’));
});
// 压缩CSS
gulp.task(‘styles’, function() {
return gulp.src(‘app/styles/**/*.css’)
.pipe(cleanCSS())
.pipe(gulp.dest(‘dist/styles’));
});
// 压缩HTML
gulp.task(‘html’, function() {
return gulp.src(‘dist/**/*.html’)
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest(‘dist’));
});
// 默认任务
gulp.task(‘default’, gulp.series(‘copy-html’, ‘scripts’, ‘styles’, ‘html’));
安装Gulp插件:
npm install –save-dev gulp-uglify gulp-concat gulp-clean-css gulp-htmlmin
运行构建:
gulp
这将生成一个
dist
目录,包含优化后的代码。
二、开发环境配置
2.1 版本控制(Git)
使用Git进行版本控制是开发的基本要求。
初始化Git仓库:
git init
创建
.gitignore
文件:
# 忽略Node.js依赖
node_modules/
# 忽略Bower依赖(如果使用)
bower_components/
# 忽略构建输出
dist/
build/
# 忽略环境变量文件
.env
# 忽略日志文件
*.log
# 忽略系统文件
.DS_Store
Thumbs.db
提交初始代码:
git add .
git commit -m “Initial commit”
2.2 代码质量工具
2.2.1 ESLint
安装ESLint来检查JavaScript代码质量。
npm install –save-dev eslint eslint-config-angular eslint-plugin-angular
创建
.eslintrc.json
:
{
“extends”: “angular”,
“env”: {
“browser”: true,
“jasmine”: true
},
“rules”: {
“no-console”: “off”
}
}
运行ESLint:
npx eslint app/scripts/
2.2.2 JSHint(可选)
另一个流行的JavaScript代码质量工具。
npm install –save-dev jshint
创建
.jshintrc
:
{
“asi”: false,
“browser”: true,
“curly”: true,
“eqeqeq”: true,
“eqnull”: true,
“expr”: true,
“immed”: true,
“newcap”: true,
“noarg”: true,
“smarttabs”: true,
“sub”: true,
“undef”: true,
“unused”: true
}
2.3 自动化测试
2.3.1 安装Karma和Jasmine
Karma是测试运行器,Jasmine是测试框架。
npm install –save-dev karma karma-jasmine karma-chrome-launcher karma-coverage
初始化Karma:
npx karma init
选择Jasmine作为框架,Chrome作为浏览器,然后生成
karma.conf.js
。
配置
karma.conf.js
(部分):
module.exports = function(config) {
config.set({
basePath: ”,
frameworks: [‘jasmine’],
files: [
‘node_modules/angular/angular.js’,
‘node_modules/angular-route/angular-route.js’,
‘node_modules/angular-mocks/angular-mocks.js’,
‘app/scripts/**/*.js’,
‘test/**/*.spec.js’
],
exclude: [],
preprocessors: {
‘app/scripts/**/*.js’: [‘coverage’]
},
reporters: [‘progress’, ‘coverage’],
coverageReporter: {
type: ‘html’,
dir: ‘coverage/’
},
browsers: [‘Chrome’],
singleRun: true
});
};
创建测试文件
test/mainController.spec.js
:
describe(‘MainController’, function() {
var $controller, $scope;
beforeEach(module(‘myApp’));
beforeEach(inject(function(_$controller_, $rootScope) {
$scope = $rootScope.$new();
$controller = _$controller_(‘MainController’, { $scope: $scope });
}));
it(‘should have a message’, function() {
expect($scope.mainCtrl.message).toBe(‘Hello from AngularJS!’);
});
});
运行测试:
npx karma start
2.4 开发服务器配置
2.4.1 使用BrowserSync(可选)
BrowserSync可以提供实时重载功能。
npm install –save-dev browser-sync
创建
gulpfile.js
中的BrowserSync任务:
const browserSync = require(‘browser-sync’);
gulp.task(‘serve’, function() {
browserSync.init({
server: {
baseDir: ‘./app’
}
});
gulp.watch(‘app/**/*.html’).on(‘change’, browserSync.reload);
gulp.watch(‘app/scripts/**/*.js’).on(‘change’, browserSync.reload);
gulp.watch(‘app/styles/**/*.css’).on(‘change’, browserSync.reload);
});
gulp.task(‘default’, gulp.series(‘copy-html’, ‘scripts’, ‘styles’, ‘html’, ‘serve’));
运行开发服务器:
gulp serve
三、生产环境配置
3.1 构建生产版本
3.1.1 使用Gulp构建
前面已经创建了基本的Gulp任务,现在可以扩展它以生成生产版本。
扩展
gulpfile.js
:
const del = require(‘del’);
const runSequence = require(‘run-sequence’);
// 清理dist目录
gulp.task(‘clean’, function() {
return del([‘dist/**/*’]);
});
// 复制字体文件(如果有)
gulp.task(‘fonts’, function() {
return gulp.src(‘app/fonts/**/*’)
.pipe(gulp.dest(‘dist/fonts’));
});
// 复制图片(如果有)
gulp.task(‘images’, function() {
return gulp.src(‘app/images/**/*’)
.pipe(gulp.dest(‘dist/images’));
});
// 构建任务
gulp.task(‘build’, function(callback) {
runSequence(
‘clean’,
[‘copy-html’, ‘scripts’, ‘styles’, ‘fonts’, ‘images’],
‘html’,
callback
);
});
运行构建:
gulp build
3.1.2 使用Webpack(现代方法)
虽然AngularJS项目通常使用Gulp/Grunt,但也可以使用Webpack进行构建。
安装Webpack及相关插件:
npm install –save-dev webpack webpack-cli webpack-dev-server
npm install –save-dev babel-loader @babel/core @babel/preset-env
npm install –save-dev html-webpack-plugin css-loader style-loader
创建
webpack.config.js
:
const path = require(‘path’);
const HtmlWebpackPlugin = require(‘html-webpack-plugin’);
module.exports = {
entry: ‘./app/scripts/app.js’,
output: {
path: path.resolve(__dirname, ‘dist’),
filename: ‘bundle.js’
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: ‘babel-loader’,
options: {
presets: [‘@babel/preset-env’]
}
}
},
{
test: /\.css$/,
use: [‘style-loader’, ‘css-loader’]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: ‘./app/index.html’,
filename: ‘index.html’
})
],
devServer: {
contentBase: path.join(__dirname, ‘dist’),
compress: true,
port: 9000
}
};
修改
app/index.html
以适应Webpack:
{{ mainCtrl.message }}
修改
app/scripts/app.js
以包含CSS:
‘use strict’;
// 引入CSS
require(‘../styles/main.css’);
// 定义AngularJS应用模块
angular.module(‘myApp’, [‘ngRoute’])
.config([‘$routeProvider’, function($routeProvider) {
$routeProvider
.when(‘/’, {
templateUrl: ‘views/main.html’,
controller: ‘MainController’,
controllerAs: ‘mainCtrl’
})
.otherwise({
redirectTo: ‘/’
});
}]);
运行Webpack开发服务器:
npx webpack serve
构建生产版本:
npx webpack –mode production
3.2 服务器配置
3.2.1 Nginx配置
Nginx是一个高性能的HTTP服务器,常用于生产环境。
安装Nginx:
# Ubuntu/Debian
sudo apt-get install nginx
# CentOS/RHEL
sudo yum install nginx
配置Nginx(示例):
创建
/etc/nginx/sites-available/my-angularjs-app
:
server {
listen 80;
server_name example.com www.example.com;
root /path/to/your/dist;
index index.html;
# 启用Gzip压缩
gzip on;
gzip_types text/plain text/css application/javascript application/json text/xml application/xml application/xml+rss text/javascript;
# 处理AngularJS的HTML5模式
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control “public, immutable”;
}
# 安全头
add_header X-Frame-Options “SAMEORIGIN”;
add_header X-Content-Type-Options “nosniff”;
add_header X-XSS-Protection “1; mode=block”;
# 限制请求大小
client_max_body_size 10M;
# 代理API请求(如果有后端)
location /api/ {
proxy_pass http://backend-server:port;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
启用站点:
sudo ln -s /etc/nginx/sites-available/my-angularjs-app /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置
sudo systemctl reload nginx
3.2.2 Apache配置
如果使用Apache服务器:
安装Apache:
# Ubuntu/Debian
sudo apt-get install apache2
# CentOS/RHEL
sudo yum install httpd
配置虚拟主机(示例):
创建
/etc/apache2/sites-available/my-angularjs-app.conf
:
ServerName example.com
ServerAlias www.example.com
DocumentRoot /path/to/your/dist
# 启用mod_rewrite
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# 启用Gzip压缩
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
# 处理AngularJS的HTML5模式
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
# 静态资源缓存
Header set Cache-Control “max-age=31536000, public”
# 安全头
Header always set X-Frame-Options “SAMEORIGIN”
Header always set X-Content-Type-Options “nosniff”
Header always set X-XSS-Protection “1; mode=block”
启用站点:
sudo a2ensite my-angularjs-app
sudo systemctl reload apache2
3.3 HTTPS配置
3.3.1 使用Let’s Encrypt获取免费SSL证书
安装Certbot:
# Ubuntu/Debian
sudo apt-get install certbot python3-certbot-nginx
# CentOS/RHEL
sudo yum install certbot python3-certbot-nginx
获取并安装证书:
sudo certbot –nginx -d example.com -d www.example.com
自动续期:
Certbot会自动设置cron任务,但可以手动测试:
sudo certbot renew –dry-run
3.4 环境变量管理
在AngularJS中,通常使用常量服务来管理环境变量。
创建环境配置服务
app/scripts/services/config.js
:
‘use strict’;
angular.module(‘myApp’)
.constant(‘Config’, {
API_URL: ‘https://api.example.com’,
DEBUG: false,
VERSION: ‘1.0.0’
});
在控制器中使用:
‘use strict’;
angular.module(‘myApp’)
.controller(‘MainController’, function(Config) {
this.message = ‘Hello from AngularJS!’;
this.apiUrl = Config.API_URL;
});
对于不同环境,可以使用构建过程替换配置:
使用Gulp替换环境变量:
const replace = require(‘gulp-replace’);
const argv = require(‘yargs’).argv;
gulp.task(‘config’, function() {
const env = argv.env || ‘development’;
const config = {
development: {
API_URL: ‘http://localhost:3000’,
DEBUG: true
},
production: {
API_URL: ‘https://api.example.com’,
DEBUG: false
}
};
return gulp.src(‘dist/scripts/services/config.js’)
.pipe(replace(/API_URL:\s*[‘”][^’”]+[‘”]/, `API_URL: ‘${config[env].API_URL}’`))
.pipe(replace(/DEBUG:\s*(true|false)/, `DEBUG: ${config[env].DEBUG}`))
.pipe(gulp.dest(‘dist/scripts/services’));
});
构建时指定环境:
gulp build –env=production
四、常见部署问题与解决方案
4.1 路由问题(HTML5模式)
问题描述:
在AngularJS中使用HTML5模式(
$locationProvider.html5Mode(true)
)时,直接访问子路由或刷新页面会导致404错误。
解决方案:
服务器端配置
:确保服务器配置了重写规则,将所有非静态文件请求重定向到
index.html
。
Nginx配置:
location / {
try_files $uri $uri/ /index.html;
}
Apache配置:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
设置
标签
:
在
index.html
的
中添加:
配置
$locationProvider
:
angular.module(‘myApp’)
.config([‘$locationProvider’, function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
}]);
4.2 跨域问题(CORS)
问题描述:
前端应用与后端API不在同一个域时,浏览器会阻止请求。
解决方案:
后端配置CORS头
:
在后端服务器响应中添加:
Access-Control-Allow-Origin: https://your-frontend-domain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
使用代理
:
在开发环境中,可以使用代理避免CORS:
Webpack Dev Server代理:
devServer: {
proxy: {
‘/api’: {
target: ‘http://localhost:3000’,
changeOrigin: true,
pathRewrite: {‘^/api’: ”}
}
}
}
Gulp BrowserSync代理:
browserSync.init({
server: {
baseDir: ‘./app’
},
proxy: ‘http://localhost:3000’,
port: 3000
});
JSONP(仅限GET请求):
angular.module(‘myApp’)
.controller(‘MainController’, function($http) {
$http.jsonp(‘http://example.com/api?callback=JSON_CALLBACK’)
.then(function(response) {
console.log(response.data);
});
});
4.3 性能优化问题
问题描述:
应用加载慢、内存泄漏、响应不及时。
解决方案:
4.3.1 代码分割与懒加载
使用
ocLazyLoad
(AngularJS懒加载模块):
安装:
npm install oclazyload
配置:
angular.module(‘myApp’, [‘oc.lazyLoad’])
.config([‘$ocLazyLoadProvider’, function($ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
debug: false,
events: true
});
}])
.controller(‘MainController’, function($ocLazyLoad, $state) {
// 懒加载模块
$ocLazyLoad.load(‘scripts/lazyModule.js’).then(function() {
// 模块加载完成后的逻辑
});
});
4.3.2 减少 watchers 数量
问题:
AngularJS的双向绑定依赖于 watchers,过多的 watchers 会严重影响性能。
解决方案:
使用单次绑定(
::
)
:
避免在模板中使用复杂表达式
:
“`javascript
// 不推荐
{{ calculateTotal() }}
// 推荐:在控制器中计算
$scope.total = calculateTotal();
{{ total }}
3. **使用 `track by` 提高 `ng-repeat` 性能**:
“`html
限制
$digest
循环
:
// 使用 $watch 替代 $scope.$apply
$scope.$watch(‘someVar’, function(newVal, oldVal) {
if (newVal !== oldVal) {
// 只在需要时触发更新
}
});
4.3.3 内存泄漏预防
常见原因:
未取消的事件监听器
未销毁的定时器
未清理的 DOM 事件
解决方案:
在
$destroy
事件中清理
:
angular.module(‘myApp’)
.controller(‘MainController’, function($scope, $interval) {
var timer = $interval(function() {
// 定时任务
}, 1000);
$scope.$on(‘$destroy’, function() {
$interval.cancel(timer);
// 清理其他资源
});
});
使用
$rootScope
谨慎
:
避免在
$rootScope
上绑定大量数据。
使用
one-time binding
:
如前所述,使用
::
减少不必要的 watchers。
4.4 安全问题
4.4.1 XSS(跨站脚本攻击)
解决方案:
使用 AngularJS 的内置转义
:
AngularJS 默认会转义插值表达式中的内容。
使用
ng-bind-html
需要
$sce
严格上下文转义
:
angular.module(‘myApp’)
.controller(‘MainController’, function($sce, $scope) {
$scope.trustedHtml = $sce.trustAsHtml(‘安全HTML‘);
});
避免使用
ng-bind-html
处理用户输入
:
除非明确需要,否则不要将用户输入作为HTML渲染。
4.4.2 CSRF(跨站请求伪造)
解决方案:
使用 CSRF Token
:
angular.module(‘myApp’)
.config([‘$httpProvider’, function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = ‘XSRF-TOKEN’;
$httpProvider.defaults.xsrfHeaderName = ‘X-XSRF-TOKEN’;
}]);
后端验证 Token
:
确保后端验证每个请求中的 CSRF Token。
4.4.3 敏感数据暴露
解决方案:
不要在客户端存储敏感信息
:
避免在 localStorage 或 sessionStorage 中存储 token、密码等。
使用 HTTP Only Cookies
:
对于 session token,使用 HTTP Only cookies。
环境配置分离
:
确保生产环境的 API 密钥、端点等与开发环境分离。
4.5 构建与部署自动化
4.5.1 使用 CI/CD 工具
示例:GitHub Actions
创建
.github/workflows/deploy.yml
:
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v2
– name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: ’14’
– name: Install dependencies
run: npm ci
– name: Run tests
run: npm test
– name: Build
run: npm run build
– name: Deploy to server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
source: “dist/”
target: “/var/www/my-angularjs-app”
4.5.2 Docker 化部署
创建
Dockerfile
:
# 构建阶段
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
# 复制构建产物
COPY –from=builder /app/dist /usr/share/nginx/html
# 复制Nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD [“nginx”, “-g”, “daemon off;”]
创建
nginx.conf
:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# Gzip压缩
gzip on;
gzip_types text/plain text/css application/javascript application/json text/xml application/xml application/xml+rss text/javascript;
}
构建和运行:
docker build -t my-angularjs-app .
docker run -p 8080:80 my-angularjs-app
五、优化技巧
5.1 代码优化
5.1.1 使用 Babel 转译
确保代码兼容旧浏览器。
安装 Babel:
npm install –save-dev @babel/core @babel/preset-env babel-loader
配置
.babelrc
:
{
“presets”: [“@babel/preset-env”]
}
在 Webpack 中使用:
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: ‘babel-loader’
}
}
]
}
5.1.2 依赖管理
使用
npm ci
而非
npm install
:
在 CI/CD 中,使用
npm ci
可以确保安装的依赖版本与
package-lock.json
完全一致。
5.2 资源优化
5.2.1 图片优化
使用
gulp-imagemin
:
npm install –save-dev gulp-imagemin
添加 Gulp 任务:
const imagemin = require(‘gulp-imagemin’);
gulp.task(‘images’, function() {
return gulp.src(‘app/images/**/*’)
.pipe(imagemin())
.pipe(gulp.dest(‘dist/images’));
});
5.2.2 字体优化
使用
gulp-fontmin
(如果需要):
npm install –save-dev gulp-fontmin
5.3 缓存策略
5.3.1 浏览器缓存
Nginx 配置:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 1y;
add_header Cache-Control “public, immutable”;
}
5.3.2 Service Worker(高级)
安装
sw-precache
:
npm install –save-dev sw-precache
创建 Gulp 任务:
const swPrecache = require(‘sw-precache’);
gulp.task(‘service-worker’, function(callback) {
swPrecache.write(‘dist/service-worker.js’, {
staticFileGlobs: [‘dist/**/*.{html,css,js,png,jpg,gif,svg,woff,woff2,ttf}’],
stripPrefix: ‘dist’,
runtimeCaching: [{
urlPattern: /^https:\/\/api\.example\.com/,
handler: ‘networkFirst’
}]
}, callback);
});
5.4 监控与日志
5.4.1 错误监控
使用 Sentry(示例):
安装:
npm install @sentry/browser
初始化:
“`javascript
import * as Sentry from ‘@sentry/browser’;
Sentry.init({
dsn: ‘https://your-dsn@sentry.io/project-id’,
environment: ‘production’
});
// 在AngularJS中使用
angular.module(‘myApp’)
.config([‘$provide’, function($provide) {
$provide.decorator(‘$exceptionHandler’, function($delegate) {
return function(exception, cause) {
Sentry.captureException(exception);
$delegate(exception, cause);
};
});
}]);
#### 5.4.2 性能监控
**使用 `performance.mark` 和 `performance.measure`:**
“`javascript
// 在关键代码处标记
performance.mark(‘start-operation’);
// … 执行操作
performance.mark(‘end-operation’);
performance.measure(‘operation-duration’, ‘start-operation’, ‘end-operation’);
// 获取测量结果
const measures = performance.getEntriesByName(‘operation-duration’);
console.log(‘Duration:’, measures[0].duration);
六、总结
AngularJS项目的部署是一个涉及多个环节的复杂过程,从开发环境的搭建到生产环境的配置,每一步都需要仔细规划和执行。通过本文的详细指南,你应该能够:
正确搭建开发环境
:包括Node.js、npm、Bower、Gulp等工具的安装和配置。
配置开发环境
:包括版本控制、代码质量工具、自动化测试和开发服务器。
构建生产版本
:使用Gulp或Webpack进行代码优化和打包。
配置生产服务器
:使用Nginx或Apache,并启用HTTPS。
解决常见问题
:如路由问题、跨域问题、性能问题和安全问题。
应用优化技巧
:包括代码优化、资源优化、缓存策略和监控。
记住,虽然AngularJS是一个较老的框架,但通过现代工具和最佳实践,仍然可以构建和部署高性能、安全的应用。随着技术的不断发展,建议逐步迁移到更现代的框架,如Angular 2+、React或Vue,以获得更好的开发体验和性能。
附录:常用命令速查表
任务
命令
安装依赖
npm install
或
bower install
运行开发服务器
http-server app
或
gulp serve
运行测试
npx karma start
构建生产版本
gulp build
或
npm run build
运行ESLint
npx eslint app/scripts/
运行Docker构建
docker build -t my-app .
运行Docker容器
docker run -p 8080:80 my-app
通过遵循这些步骤和最佳实践,你可以确保你的AngularJS项目在生产环境中稳定、高效地运行。