根据环境在angularjs项目中设置基本URL

时间:2022-04-26 20:34:38

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'
    ]);
});