如何将Yeoman项目部署到子目录?

时间:2015-02-28 12:07:23

标签: angularjs yeoman

我正在使用grunt-aws-s3插件来部署我的dist文件夹,而且当我将其部署到子目录时,我的所有资产都无法正常链接。例如,它一直尝试从mydomain.com/styles/fonts/font.woff而不是mydomain.com/staging/styles/fonts/font.woff的根目录中检索我的网络字体。此外,它一直试图通过http而不是https来抓取我的模板。我尝试了各种方法来链接我的CSS(相对而且只是文件名),但它们似乎都没有用。我该如何解决这个问题?

@font-face {
  font-family: 'moneytree';
  src:url('/styles/fonts/webfont.eot');
  src:url('/styles/fonts/webfont.eot') format('embedded-opentype'),
  url('/styles/fonts/webfont.woff') format('woff'),
  url('/styles/fonts/webfont.ttf') format('truetype'),
  url('/styles/fonts/webfont.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}


module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  // Time how long tasks take. Can help when optimizing build times
  require('time-grunt')(grunt);

  // Configurable paths for the application
  var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
  };

  // Define the configuration for all the tasks
  grunt.initConfig({

    // Project settings
    yeoman: appConfig,

    // This creates a config file with a bunch of constants for Angular and then we load it into setting.coffee
    ngconstant: {
      options: {
        space: '  ',
        name: 'envConfig',
        dest: '.tmp/scripts/initializers/env-config.js',
        wrap: '"use strict";\n\n {%= __ngModule %}'
      },
      // Environment targets
      development: {
        constants: {
          ENV: {
            name: 'development',
            app_id: '',
            secret: '',
            host: 'https://test.com',
            version: 'v8/api'
          }
        }
      },
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      options: {
        nospawn: false,
        livereload: true
      },
      coffee: {
        files: ['<%= yeoman.app %>/scripts/**/*.{coffee,litcoffee,coffee.md}'],
        tasks: ['newer:coffee:dist']
      },
      coffeeTest: {
        files: ['test/unit/**/*.{coffee,litcoffee,coffee.md}'],
        tasks: ['newer:coffee:test', 'karma']
      },
      bower: {
        files: ['bower.json'],
        tasks: ['wiredep']
      },
      js: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
        tasks: ['newer:jshint:all'],
        options: {
          livereload: true
        }
      },
      jsTest: {
        files: ['test/unit/{,*/}*.js'],
        tasks: ['newer:jshint:test', 'karma']
      },
      compass: {
        files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass:server', 'autoprefixer']
      },
      gruntfile: {
        files: ['Gruntfile.js']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= yeoman.app %>/{,*/}{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          '<%= yeoman.app %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    // The actual grunt server settings
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: 'localhost',
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              connect.static('.tmp'),
              connect.static('test'),
              connect().use(
                '/bower_components',
                connect.static('./bower_components')
              ),
              connect.static(appConfig.app)
            ];
          }
        }
      },
      dist: {
        options: {
          open: true,
          base: '<%= yeoman.dist %>'
        }
      }
    },
    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
      options: {
        jshintrc: '.jshintrc',
        reporter: require('jshint-stylish')
      },
      all: [
        'Gruntfile.js',
        '<%= yeoman.app %>/scripts/{,*/}*.js'
      ],
      test: {
        options: {
          jshintrc: 'test/.jshintrc'
        },
        src: ['test/unit/{,*/}*.js']
      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            '.tmp',
            '<%= yeoman.dist %>/*',
            '!<%= yeoman.dist %>/.git*'
          ]
        }]
      },
      server: '.tmp'
    },

    // Adds browser vendor prefixe to the CSS styles. For example, give the selector
    // :fullscreen a {}, it will generate all the different browser prefixes such as :-webkit-full-screen a {}, etc..
    autoprefixer: {
      options: {
        browsers: ['last 1 version']
      },
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/styles/',
          src: '{,*/}*.css',
          dest: '.tmp/styles/'
        }]
      }
    },

    // Automatically inject Bower components into the app
    wiredep: {
      app: {
        src: ['<%= yeoman.app %>/index.html'],
          ignorePath:  /\.\.\//
      },
      sass: {
        src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
          ignorePath: /(\.\.\/){1,2}bower_components\//
      }
    },

    // Compiles CoffeeScript to JavaScript
    coffee: {
      options: {
        sourceMap: true,
        sourceRoot: ''
      },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/scripts',
          src: '**/*.coffee',
          dest: '.tmp/scripts',
          ext: '.js'
        }]
      },
      unit: {
        files: [{
          expand: true,
          cwd: 'test/unit',
          src: '**/*.coffee',
          dest: '.tmp/unit',
          ext: '.js'
        }]
      },
      e2e: {
        files: [{
          expand: true,
          cwd: 'test/e2e',
          src: '**/*.coffee',
          dest: '.tmp/e2e',
          ext: '.js'
        }]
      }
    },

    // Compiles Sass to CSS and generates necessary files if requested
    compass: {
      options: {
        sassDir: '<%= yeoman.app %>/styles',
        cssDir: '.tmp/styles',
        generatedImagesDir: '.tmp/images/generated',
        imagesDir: '<%= yeoman.app %>/images',
        javascriptsDir: '<%= yeoman.app %>/scripts',
        fontsDir: '<%= yeoman.app %>/styles/fonts',
        importPath: 'bower_components',
        httpImagesPath: '/images',
        httpGeneratedImagesPath: '/images/generated',
        httpFontsPath: '/styles/fonts',
        relativeAssets: false,
        assetCacheBuster: false,
        raw: 'Sass::Script::Number.precision = 10\n'
      },
      dist: {
        options: {
          generatedImagesDir: '<%= yeoman.dist %>/images/generated',
          relativeAssets: false
        }
      },
      test: {
        options: {
          generatedImagesDir: '.tmp/images/generated',
          imagesDir: '<%= yeoman.app %>/images',
          relativeAssets: false
        }
      },
      server: {
        options: {
          debugInfo: true
        }
      }
    },

    // Renames files for browser caching purposes
    filerev: {
      dist: {
        src: [
          '<%= yeoman.dist %>/scripts/{,*/}*.js',
          '<%= yeoman.dist %>/styles/{,*/}*.css',
          '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
          '!<%= yeoman.dist %>/images/transactions*/*.svg',
          '<%= yeoman.dist %>/styles/fonts/*'
        ]
      }
    },

    // Reads HTML for usemin blocks to enable smart builds that automatically
    // concat, minify and revision files. Creates configurations in memory so
    // additional tasks can operate on them
    useminPrepare: {
      html: '<%= yeoman.app %>/index.html',
      options: {
        dest: '<%= yeoman.dist %>',
        flow: {
          html: {
            steps: {
              js: ['concat', 'uglifyjs'],
              css: ['cssmin']
            },
            post: {}
          }
        }
      }
    },

    // Performs rewrites based on filerev and the useminPrepare configuration
    usemin: {
      html: ['<%= yeoman.dist %>/{,*/}*.html'],
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
      options: {
        assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images']
      }
    },

    // The following *-min tasks produce minified files in the dist folder
    cssmin: {
      options: {
        root: '<%= yeoman.app %>'
      }
    },

    imagemin: {
      options: { cache: false },
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '**/*.{png,jpg,jpeg,gif}',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

    svgmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= yeoman.app %>/images',
          src: '**/*.svg',
          dest: '<%= yeoman.dist %>/images'
        }]
      }
    },

    htmlmin: {
      dist: {
        options: {
          collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeCommentsFromCDATA: true,
          removeOptionalTags: true
        },
        files: [{
          expand: true,
          cwd: '<%= yeoman.dist %>',
          src: ['*.html', 'views/{,*/}{,*/}*.html'],
          dest: '<%= yeoman.dist %>'
        }]
      }
    },
    // Makes your minification safe for Angular's dependecy injection.
    ngAnnotate: {
      options: {
        // Task-specific options go here.
        singleQuotes: true
      },
      dist: {
        // Target-specific file lists and/or options go here.
        files: [
          {
            expand: true,
            cwd: '.tmp/concat/scripts',
            src: '*.js',
            dest: '.tmp/concat/scripts'
          }
        ]
      }
    },
    // Replace Google CDN references
    cdnify: {
      dist: {
        html: ['<%= yeoman.dist %>/*.html']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '**/*.{jpg,ico,png,txt}',
            '.htaccess',
            '*.html',
            'views/{,*/}{,*/}*.html',
            'images/**/*.{webp}',
            'styles/fonts/*'
          ]
        },
        {
            expand: true,
            cwd: '<%= yeoman.app %>/bower_components/bootstrap/dist/styles/fonts',
            src: ['**'],
            dest: '<%= yeoman.dist %>/bower_components/bootstrap/dist/styles/fonts'
        },
        {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
      server: [
        'coffee:dist',
        'compass:server'
      ],
      test: [
        'compass:test',
        'coffee:e2e',
        'coffee:dist'
      ],
      unitTest: [
        'compass:test',
        'coffee:unit',
        'coffee:dist'
      ],
      dist: [
        'coffee:dist',
        'compass:dist',
        'imagemin:dist',
        'svgmin:dist'
      ]
    },

    // By default, your `index.html`'s <!-- Usemin block --> will take care of
    // minification. These next options are pre-configured if you do not wish
    // to use the Usemin blocks.
    // cssmin: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/styles/main.css': [
    //         '.tmp/styles/{,*/}*.css',
    //         '<%= yeoman.app %>/styles/{,*/}*.css'
    //       ]
    //     }
    //   }
    // },
    // uglify: {
    //   dist: {
    //     files: {
    //       '<%= yeoman.dist %>/scripts/scripts.js': [
    //         '<%= yeoman.dist %>/scripts/scripts.js'
    //       ]
    //     }
    //   }
    // },
    // concat: {
    //   dist: {}
    // },

    // Test settings
    karma: {
      unit: {
        configFile: 'karma.conf.js',
        singleRun: true
      }
    },
    protractor: {
      options: {
        // You NEVER want this because if there is an error, it will not return the correct exit status
        keepAlive: false,
        configFile: 'protractor.conf.js',
        noColor: false
        //debug: true
      },
      run: {}
    },
    aws: grunt.file.readJSON('aws-keys.json'), // Read the file
    aws_s3: {
      options: {
        region: 'ap-northeast-1',
        uploadConcurrency: 5, // 5 simultaneous uploads
        downloadConcurrency: 5 // 5 simultaneous downloads
      },
      staging: {
        options: {
          bucket: 'staging-bucket',
          differential: true, // Only uploads the files that have changed
          params: {
            CacheControl: "no-cache,no-store"
          }
        },
        files: [
          {dest: '/test', 'action': 'delete'},
          {expand: true, cwd: 'dist/', src: ['**'], dest: '/test'}
        ]
      },
      clean_production: {
        options: {
          bucket: 'my-wonderful-production-bucket',
          debug: true // Doesn't actually delete but shows log
        },
        files: [
          {dest: 'app/', action: 'delete'},
          {dest: 'assets/', exclude: "**/*.tgz", action: 'delete'}, // will not delete the tgz
          {dest: 'assets/large/', exclude: "**/*copy*", flipExclude: true, action: 'delete'}, // will delete everything that has copy in the name
        ]
      },
      download_production: {
        options: {
          bucket: 'my-wonderful-production-bucket'
        },
        files: [
          {dest: 'app/', cwd: 'backup/', action: 'download'}, // Downloads the content of app/ to backup/
          {dest: 'assets/', cwd: 'backup-assets/', exclude: "**/*copy*", action: 'download'}, // Downloads everything which doesn't have copy in the name
        ]
      },
      secret: {
        options: {
          bucket: 'my-wonderful-private-bucket',
          access: 'private'
        },
        files: [
          {expand: true, cwd: 'secret_garden/', src: ['*.key'], dest: 'secret/'},
        ]
      },
    },
    dom_munger: {
      e2e: {
        options: {
          append: {
            selector: 'body',
            html: '<script src="bower_components/angular-mocks/angular-mocks.js"></script>\
            <script src="e2e/httpbackend_setup.js"></script>'
          }
        },
        src: '<%= yeoman.app %>/index.html',
        dest: '.tmp/e2e.html'
      }
    }

  });

  grunt.registerTask('serve', function (target) {
    if (target === 'dist') {
      return grunt.task.run(['connect:dist:keepalive']);
    }

    grunt.task.run([
      'clean:server',
      'ngconstant:development',
      'wiredep',
      'concurrent:server',
      'autoprefixer',
      'connect:livereload',
      'watch'
    ]);
  });

  grunt.registerTask('build:development', [
    'clean:dist',
    'wiredep',
    'ngconstant:development',
    'useminPrepare',
    'concurrent:dist',
    'autoprefixer',
    'concat',
    'ngAnnotate',
    'copy:dist',
    'cdnify',
    'cssmin',
    'uglify',
    'filerev',
    'usemin',
    'htmlmin'
  ]);

  grunt.registerTask('deploy:staging', [
    'build:development',
    'aws_s3:staging'
  ]);

编辑:我设法让CSS中的字体相对运行,但仍然无法相对加载HTML嵌入图像。此外,仍然不明白为什么我的字体是通过HTTP检索而不是HTTPS导致浏览器出现混合内容错误。

假设您的字体位于app/styles/fonts(注意到font-url功能而不是url()

@font-face {
  font-family:'webfont';
  src: font-url('webfont.eot');
  src: font-url('webfont.eot') format('embedded-opentype'),
   font-url('webfont.woff') format('woff'),
   font-url('webfont.ttf') format('truetype'),
   font-url('webfont.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}

对于我在Gruntfile中的指南针(httpFontsPath)和cssmin(noRebase)配置:

  compass: {
      options: {
        sassDir: '<%= yeoman.app %>/styles',
        cssDir: '.tmp/styles',
        generatedImagesDir: '.tmp/images/generated',
        imagesDir: '<%= yeoman.app %>/images',
        javascriptsDir: '<%= yeoman.app %>/scripts',
        fontsDir: '<%= yeoman.app %>/styles/fonts',
        importPath: 'bower_components',
        httpImagesPath: 'images',
        httpGeneratedImagesPath: '/images/generated',
        httpFontsPath: 'fonts',
        relativeAssets: false,
        assetCacheBuster: false,
        raw: 'Sass::Script::Number.precision = 10\n'
      }
}



cssmin: {
  options: {
    root: '<%= yeoman.app %>',
    noRebase: true
  }
}

1 个答案:

答案 0 :(得分:0)

您可以使路径相对,例如:

@font-face {
  font-family: 'moneytree';
  src:url('fonts/webfont.eot');
  src:url('fonts/webfont.eot') format('embedded-opentype'),
  url('fonts/webfont.woff') format('woff'),
  url('fonts/webfont.ttf') format('truetype'),
  url('fonts/webfont.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}