mgechev / angular-seed

🌱 [Deprecated] Extensible, reliable, modular, PWA ready starter project for Angular (2 and beyond) with statically typed build and AoT compilation
https://mgechev.github.io/angular-seed
MIT License
4.57k stars 1.45k forks source link

Font files are missing in build.prod #404

Closed heikoholland closed 8 years ago

heikoholland commented 8 years ago

When building a prod package and fonts are included via css they won't get included in the prod package.

Current workaround is to copy all files manually in the app/ directory.

I think this could be done in a gulp task. Am I right?

mgechev commented 8 years ago

If the font files are located somewhere inside assets then the task build.assets.prod will copy them.

If you're using fonts from node_modules you need to explicitly specify that the need to be copied in config.ts

bertvh commented 8 years ago

I've tried adding the bootstrap glyphicons by adding this

{ src: 'bootstrap/dist/fonts/glyphicons-halflings-regular.eot', inject: true}

to PROD_NPM_DEPENDENCIES.

Nothing is getting copied/injected. Not sure where to look.

ludohenin commented 8 years ago

@bertvh Can you try { src: 'bootstrap/dist/fonts/**/*', dest: FONTS_DIR }. Fonts should not be injected.

bertvh commented 8 years ago

Doesn't seem to do anything. If I don't inject the fonts, I need to get them in a location relative to the aggregated minified css (in this case bootstrap.css refers to ./fonts/glyphicons-...). Maybe I've changed something locally. Will look further. Thanks.

nkmdev commented 8 years ago

I too have the same problem. Can't copy fonts.

bertvh commented 8 years ago

Eventually, I fixed this by writing a small plugin based on gulp-extract-css-urls. What is does is parse the css file and then copy all dependencies to the correct level in your output folder.

This works for me but is not heavily tested!

You can add this in build.html_css.prod.ts:

// ...
import * as through from 'through2';
import {readFileSync} from 'fs';

var url = require('rework-plugin-url');
var rework = require('rework');
var vinylFile = require('vinyl-file');
// ...

/**
   * This is a gulp plugin that takes a css file and outputs the files that the css file refers to via url().
   * Heavily inspired on https://github.com/skyrpex/gulp-extract-css-urls/blob/master/src/index.js
   * @returns {NodeJS.ReadWriteStream}
   */
  var includeCssResources = function () {
    return through.obj(function (file, encoding, callback) {

      var self = this;

      // callback for the rework-url plugin
      var handle = function (url:string) {
        if (url.match(/^data:/) || url.indexOf('#') >= 0) {
          return url;
        }
        self.push(vinylFile.readSync(url, {cwd: dirname(file.path)}));
        return url;
      };

      // Read css file and give it to rework for parsing
      var cssContent:Buffer = readFileSync(file.path);
      rework(cssContent.toString()).use(url(handle));

      // Call this when done
      callback(/*possible error*/);
    });
  };
// Copy and concatenate all external css
    function processExternalCss() {

      // copy all dependencies from the css to the css destination
      gulp.src(getExternalCss().map(r => r.src))
        .pipe(includeCssResources())  // this does the includes
        .pipe(gulp.dest(CSS_DEST));

      return gulp.src(getExternalCss().map(r => r.src))
        //.pipe(plugins.cssnano())
        .pipe(plugins.concat(CSS_PROD_BUNDLE))
        .pipe(gulp.dest(CSS_DEST));
    }
zcsongor commented 8 years ago

This is my problem as well. Tried to copy this line to PROD_NPM_DEPENDENCIES

{ src: 'material-design-iconic-font/dist/fonts/**/*', inject: false, dest: FONTS_DEST }

but nothing happened. Isn't there any easier solution than using a plugin for this?

ludohenin commented 8 years ago

@zcsongor This was previously supported by the build.deps tasks which has been removed since then.

An easy way to add it again is to add copy tasks with the appropriate config. https://github.com/ludohenin/ng2-wp-blog/blob/master/tools/config.ts#L98-L100 https://github.com/ludohenin/ng2-wp-blog/blob/master/tools/tasks/copy.fonts.prod.ts

//cc @mgechev Do you think we should support it ?

zcsongor commented 8 years ago

Thank you!

mgechev commented 8 years ago

We should support copying fonts located inside ./src given the current copy task.

If you need to copy ones residing in node_modules you need to extend it.

dimarzionist commented 8 years ago

My version of this that works with bootstrap 3 looks something like this:

in the config.ts:

export const FONTS_DEST =${APP_DEST}/fonts; export const PROD_NPM_DEPENDENCIES: InjectableDependency[] = normalizeDependencies([

{ src: "bootstrap/dist/fonts/**", inject: false, dest: FONTS_DEST } ]);

and then 'build.fonts.prod' task:

return gulp
    .src(getFonts().map(r => r.src))
    .pipe(gulp.dest(FONTS_DEST));

function getFonts() {
    return PROD_DEPENDENCIES.filter(d => /fonts/.test(d.src));
}

I'm not sure though if it's a best place for the font files to be referenced from the array of 'InjectableDependencies' :cactus:

mgechev commented 8 years ago

@heikoholland the solution by @dimarzionist sounds like the correct one.

I agree that it doesn't sound very semantically correct. I'll rename the interface.

mgechev commented 8 years ago

Here's wiki page I added https://github.com/mgechev/angular2-seed/wiki/Add-external-fonts Let me know if you find something wrong.

ludohenin commented 8 years ago

@mgechev I don't think it will work. The src is just a string, so no chances to find a font extension in it. I'd rather map src defining a glob in build.assets.prod to copy those files with the rest. I'll try and send a PR for that.

ludohenin commented 8 years ago

build.assets.prod isn't the right place ... DEST issue :/

Dinistro commented 8 years ago

@mgechev I tested your approach but, like @ludohenin expected, it does not work.