I'm working on an AngularJs project created using Yeoman. The project uses Grunt as task manager.
我正在研究使用Yeoman创建的AngularJs项目。该项目使用Grunt作为任务管理器。
In my index.html I need to set the base url:
在我的index.html中,我需要设置基本网址:
<base href="/">
The href attribute value depends on the environment: if the environment is development I want href to be simply /
, if the environment is production the value has to be something else a/b/c
.
href属性值取决于环境:如果环境是开发,我希望href简单地为/,如果环境是生产,则值必须是a / b / c。
What are the available solutions to this problem?
这个问题有哪些可用的解决方案?
It is possible to set it dynamically at runtime using a constant from AngualrJs or it is better to set it statically at build/serve time?
可以使用AngualrJs中的常量在运行时动态设置它,还是最好在构建/服务时静态设置它?
3 个解决方案
#1
Personally I prefer to set it a build/serve time, so I don't need to change the code when I change environment.
我个人更喜欢将其设置为构建/服务时间,因此在更改环境时我不需要更改代码。
So, I can push on the server and use grunt serve:production
- you don't need to change the code, so you can use git hooks and a bash script to easily serve your code.
因此,我可以推送服务器并使用grunt serve:production - 您不需要更改代码,因此您可以使用git hooks和bash脚本轻松地为您的代码提供服务。
To achieve this in Grunt you can use ngcostant. You define the vars you want, and it creates a file named config.js (or whatever you want) that exposes your vars under ENV
(or whatever you want) using .configure()
要在Grunt中实现此目的,您可以使用ngcostant。您可以定义所需的变量,并创建一个名为config.js(或任何您想要的)的文件,使用.configure()在ENV(或任何您想要的)下公开您的变量。
Talking about your case, you can have something like this in your Gruntfile:
谈到你的情况,你可以在你的Gruntfile中有这样的东西:
ngconstant: {
options: {
space: ' ',
wrap: '"use strict";\n {%= __ngModule %}',
name: 'config'
},
vagrant: {
options: {
dest: 'app/scripts/config.js'
},
constants: {
ENV: {
name: 'vagrant',
baseUrl: 'http://192.168.33.99/api/v0',
}
}
},
test: {
options: {
dest: 'app/scripts/config.js'
},
constants: {
ENV: {
name: 'test',
baseUrl: 'http://test.example.com/api/v0',
}
}
},
}
Then, in your app you can take the baseUrl using ENV.baseUrl
and expose to your html file, like this (angular):
然后,在您的应用程序中,您可以使用ENV.baseUrl获取baseUrl并公开到您的html文件,如下所示(angular):
app.run(function($rootScope, ENV.baseUrl){
$rootScope.baseUrl = config.baseUrl;
});
(html)
<base ng-href="{{baseUrl}}">
So you can serve your application using grunt serve:vagrant
when you're using vagrant or grunt serve:test
when you want to run on your test server
因此,当您使用vagrant或grunt服务时,您可以使用grunt serve:vagrant为您的应用程序提供服务:当您想在测试服务器上运行时进行测试
#2
Try with grunt template package:
尝试使用grunt模板包:
Template strings can be processed manually using the provided template functions.
可以使用提供的模板函数手动处理模板字符串。
This package offers default delimiters ie. <%= placeholder %>
to replace variable values in placeholder given a that you are using Grunt.
此包提供默认分隔符,即。 <%=占位符%>在给定您正在使用Grunt的占位符中替换变量值。
Another package, grunt-processhtml provides processes html with special comments:
另一个包grunt-processhtml为进程html提供了特殊注释:
<!-- build:<type>[:target] [inline] [value] -->
...
<!-- /build -->
Example on how to use with in HTML file:
有关如何在HTML文件中使用的示例:
<!-- build:remove:staging,prod -->
<base href="/app/public/" target="_blank" />
<!-- /build -->
And on production you could do the following:
在生产中,您可以执行以下操作:
<!-- build:[href] a/b/c -->
<base href="/app/public/" target="_blank" />
<!-- /build -->
<!-- will be changed to -->
<base href="a/b/c/" target="_blank" />
#3
My approach was to not include any other dependencies at all (yeoman has enough already). I simply used the blockReplacement
feature of usemin
and added a dev
target to my build
task.
我的方法是根本不包括任何其他依赖项(自耕农已经足够了)。我只是使用了usemin的blockReplacement功能,并在我的构建任务中添加了一个dev目标。
This allows me to use grunt build
for production distribution, grunt build:dev
for development distribution (remote) and grunt serve
for normal local development.
这允许我使用grunt构建用于生产分发,grunt构建:dev用于开发分发(远程)和grunt服务用于正常的本地开发。
In my html
:
在我的HTML中:
<!-- build:baseUrl /somepath/ -->
<base href="/">
<!-- endbuild -->
In my Gruntfile.js
:
在我的Gruntfile.js中:
...
var appConfig = {
app: require('./bower.json').appPath || 'app',
dist: 'dist',
dev: false // added dev boolean at ~ line 22
};
...
assetsDirs: [
'<%= yeoman.dist %>',
'<%= yeoman.dist %>/images',
'<%= yeoman.dist %>/styles'
],
// added blockReplacements at ~ line 250
blockReplacements: {
baseUrl: function (block) {
if (appConfig.dev) {
return ['<base href="', block.dest, '">'].join('');
}
}
}
...
// Altered the default build task to accept a target
grunt.registerTask('build', 'Compile the code base for distribution', function (target) {
if (target === 'dev') {
appConfig.dev = true;
}
grunt.task.run([
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
});
#1
Personally I prefer to set it a build/serve time, so I don't need to change the code when I change environment.
我个人更喜欢将其设置为构建/服务时间,因此在更改环境时我不需要更改代码。
So, I can push on the server and use grunt serve:production
- you don't need to change the code, so you can use git hooks and a bash script to easily serve your code.
因此,我可以推送服务器并使用grunt serve:production - 您不需要更改代码,因此您可以使用git hooks和bash脚本轻松地为您的代码提供服务。
To achieve this in Grunt you can use ngcostant. You define the vars you want, and it creates a file named config.js (or whatever you want) that exposes your vars under ENV
(or whatever you want) using .configure()
要在Grunt中实现此目的,您可以使用ngcostant。您可以定义所需的变量,并创建一个名为config.js(或任何您想要的)的文件,使用.configure()在ENV(或任何您想要的)下公开您的变量。
Talking about your case, you can have something like this in your Gruntfile:
谈到你的情况,你可以在你的Gruntfile中有这样的东西:
ngconstant: {
options: {
space: ' ',
wrap: '"use strict";\n {%= __ngModule %}',
name: 'config'
},
vagrant: {
options: {
dest: 'app/scripts/config.js'
},
constants: {
ENV: {
name: 'vagrant',
baseUrl: 'http://192.168.33.99/api/v0',
}
}
},
test: {
options: {
dest: 'app/scripts/config.js'
},
constants: {
ENV: {
name: 'test',
baseUrl: 'http://test.example.com/api/v0',
}
}
},
}
Then, in your app you can take the baseUrl using ENV.baseUrl
and expose to your html file, like this (angular):
然后,在您的应用程序中,您可以使用ENV.baseUrl获取baseUrl并公开到您的html文件,如下所示(angular):
app.run(function($rootScope, ENV.baseUrl){
$rootScope.baseUrl = config.baseUrl;
});
(html)
<base ng-href="{{baseUrl}}">
So you can serve your application using grunt serve:vagrant
when you're using vagrant or grunt serve:test
when you want to run on your test server
因此,当您使用vagrant或grunt服务时,您可以使用grunt serve:vagrant为您的应用程序提供服务:当您想在测试服务器上运行时进行测试
#2
Try with grunt template package:
尝试使用grunt模板包:
Template strings can be processed manually using the provided template functions.
可以使用提供的模板函数手动处理模板字符串。
This package offers default delimiters ie. <%= placeholder %>
to replace variable values in placeholder given a that you are using Grunt.
此包提供默认分隔符,即。 <%=占位符%>在给定您正在使用Grunt的占位符中替换变量值。
Another package, grunt-processhtml provides processes html with special comments:
另一个包grunt-processhtml为进程html提供了特殊注释:
<!-- build:<type>[:target] [inline] [value] -->
...
<!-- /build -->
Example on how to use with in HTML file:
有关如何在HTML文件中使用的示例:
<!-- build:remove:staging,prod -->
<base href="/app/public/" target="_blank" />
<!-- /build -->
And on production you could do the following:
在生产中,您可以执行以下操作:
<!-- build:[href] a/b/c -->
<base href="/app/public/" target="_blank" />
<!-- /build -->
<!-- will be changed to -->
<base href="a/b/c/" target="_blank" />
#3
My approach was to not include any other dependencies at all (yeoman has enough already). I simply used the blockReplacement
feature of usemin
and added a dev
target to my build
task.
我的方法是根本不包括任何其他依赖项(自耕农已经足够了)。我只是使用了usemin的blockReplacement功能,并在我的构建任务中添加了一个dev目标。
This allows me to use grunt build
for production distribution, grunt build:dev
for development distribution (remote) and grunt serve
for normal local development.
这允许我使用grunt构建用于生产分发,grunt构建:dev用于开发分发(远程)和grunt服务用于正常的本地开发。
In my html
:
在我的HTML中:
<!-- build:baseUrl /somepath/ -->
<base href="/">
<!-- endbuild -->
In my Gruntfile.js
:
在我的Gruntfile.js中:
...
var appConfig = {
app: require('./bower.json').appPath || 'app',
dist: 'dist',
dev: false // added dev boolean at ~ line 22
};
...
assetsDirs: [
'<%= yeoman.dist %>',
'<%= yeoman.dist %>/images',
'<%= yeoman.dist %>/styles'
],
// added blockReplacements at ~ line 250
blockReplacements: {
baseUrl: function (block) {
if (appConfig.dev) {
return ['<base href="', block.dest, '">'].join('');
}
}
}
...
// Altered the default build task to accept a target
grunt.registerTask('build', 'Compile the code base for distribution', function (target) {
if (target === 'dev') {
appConfig.dev = true;
}
grunt.task.run([
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
});