aurelia / cli

The Aurelia 1 command line tool. Use the CLI to create projects, scaffold components, and bundle your app for release.
MIT License
407 stars 133 forks source link

Cannot add glyphicons to bootstrap resources #248

Closed AshleyGrant closed 7 years ago

AshleyGrant commented 8 years ago

I'm submitting a bug report

Please tell us about your environment:

Current behavior: Adding bootstrap's glyphicons file(s) causes the CLI to fail while bundling.

This configuration for bootstrap fails:

{
  "name": "bootstrap",
  "path": "../node_modules/bootstrap/dist",
  "main": "js/bootstrap.min",
  "deps": [
    "jquery"
  ],
  "exports": "$",
  "resources": [
    "css/bootstrap.css",
    "fonts/glyphicons-halflings-regular.woff2"
  ]
}

Here is the error messaged displayed:

Tracing bootstrap/css/bootstrap...
Tracing bootstrap/fonts/glyphicons-halflings-regular...
{ uid: 9,
  name: 'writeBundles',
  branch: false,
  error:
   { Error: ENOENT: no such file or directory, open 'C:\Users\Ashley\temp\demo\node_modules\bootstrap\dist\fonts\glyphicons-halflings-regular.js'
       at Error (native)
       at Object.fs.openSync (fs.js:640:18)
       at Object.fs.readFileSync (fs.js:508:33)
       at Object.exports.readFileSync (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\file-system.js:38:13)
       at amodroTrace.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\bundled-source.js:83:31)
       at Object.context.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:176:18)
       at Object.context.load (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:357:30)
       at Object.Module.load (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:832:29)
       at Object.Module.fetch (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:822:66)
       at Object.Module.check (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:854:30)
     errno: -4058,
     code: 'ENOENT',
     syscall: 'open',
     path: 'C:\\Users\\Ashley\\temp\\demo\\node_modules\\bootstrap\\dist\\fonts\\glyphicons-halflings-regular.js' },
  duration: [ 3, 162240291 ],
  time: 1469800371889 }
{ uid: 1,
  name: '<series>',
  branch: true,
  error:
   { Error: ENOENT: no such file or directory, open 'C:\Users\Ashley\temp\demo\node_modules\bootstrap\dist\fonts\glyphicons-halflings-regular.js'
       at Error (native)
       at Object.fs.openSync (fs.js:640:18)
       at Object.fs.readFileSync (fs.js:508:33)
       at Object.exports.readFileSync (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\file-system.js:38:13)
       at amodroTrace.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\bundled-source.js:83:31)
       at Object.context.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:176:18)
       at Object.context.load (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:357:30)
       at Object.Module.load (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:832:29)
       at Object.Module.fetch (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:822:66)
       at Object.Module.check (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:854:30)
     errno: -4058,
     code: 'ENOENT',
     syscall: 'open',
     path: 'C:\\Users\\Ashley\\temp\\demo\\node_modules\\bootstrap\\dist\\fonts\\glyphicons-halflings-regular.js' },
  duration: [ 3, 343545006 ],
  time: 1469800371900 }
{ uid: 0,
  name: '<series>',
  branch: true,
  error:
   { Error: ENOENT: no such file or directory, open 'C:\Users\Ashley\temp\demo\node_modules\bootstrap\dist\fonts\glyphicons-halflings-regular.js'
       at Error (native)
       at Object.fs.openSync (fs.js:640:18)
       at Object.fs.readFileSync (fs.js:508:33)
       at Object.exports.readFileSync (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\file-system.js:38:13)
       at amodroTrace.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\bundled-source.js:83:31)
       at Object.context.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:176:18)
       at Object.context.load (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:357:30)
       at Object.Module.load (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:832:29)
       at Object.Module.fetch (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:822:66)
       at Object.Module.check (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:854:30)
     errno: -4058,
     code: 'ENOENT',
     syscall: 'open',
     path: 'C:\\Users\\Ashley\\temp\\demo\\node_modules\\bootstrap\\dist\\fonts\\glyphicons-halflings-regular.js' },
  duration: [ 3, 345732955 ],
  time: 1469800371901 }
{ Error: ENOENT: no such file or directory, open 'C:\Users\Ashley\temp\demo\node_modules\bootstrap\dist\fonts\glyphicons-halflings-regular.js'
    at Error (native)
    at Object.fs.openSync (fs.js:640:18)
    at Object.fs.readFileSync (fs.js:508:33)
    at Object.exports.readFileSync (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\file-system.js:38:13)
    at amodroTrace.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\bundled-source.js:83:31)
    at Object.context.fileRead (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:176:18)
    at Object.context.load (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:357:30)
    at Object.Module.load (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:832:29)
    at Object.Module.fetch (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:822:66)
    at Object.Module.check (eval at <anonymous> (C:\Users\Ashley\temp\demo\node_modules\aurelia-cli\lib\build\amodro-trace\lib\loader\Loader.js:14:9), <anonymous>:854:30)
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\Users\\Ashley\\temp\\demo\\node_modules\\bootstrap\\dist\\fonts\\glyphicons-halflings-regular.js' }
benlaan commented 8 years ago

@AshleyGrant did you find a workaround for this issue?

AshleyGrant commented 8 years ago

I haven't.

EisenbergEffect commented 8 years ago

Resources only support html, CSS and JavaScript currently. Bundling other resources would require both bundling and runtime support.

On Jul 31, 2016 4:14 AM, "Ashley Grant" notifications@github.com wrote:

I haven't.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/aurelia/cli/issues/248#issuecomment-236417429, or mute the thread https://github.com/notifications/unsubscribe-auth/AAIBnRGadtXkbNZkbw19eoBAZnw3Ruccks5qbFlRgaJpZM4JYNwX .

AshleyGrant commented 8 years ago

We need to come up with a solution for this, not being able to properly support bundling bootstrap is going to be a sticking point. In the JSPM skeletons, we leave it unbundled and include the files with the exported app. Can we support something like that and still support loading the bootstrap css w/a require?

EisenbergEffect commented 8 years ago

Anything is possible. Build a solution for it and we'll get it in.

guilhermewaess commented 8 years ago

This problem affects any other style framework, like Semantic-ui (same problem here)! Questions: As a workaround, you can't put your css imports on html with link instead require? Or will be a problem because of bundle?

AshleyGrant commented 8 years ago

As long as you include those files in the set of files you ship, that'll work no problem.

len-ro commented 8 years ago

Yes, removing bootstrap from aurelia.json and adding <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css"> to index.html works around the problem. Of course you have to include this node_modules folder with your deployment.

xentenario commented 8 years ago

len-ro I fixed the issue by adding the bootstrap lib using its cdn to the app.html. It is not the best solution but it works with what we have now.

arabsight commented 8 years ago

or just copy the fonts folder to '/bootstrap/fonts', that's where bootstrap is looking for them. you can create a task to automate that and add it to the build task.

CD-UNCC commented 8 years ago

+1 for getting this addressed.

geleto commented 8 years ago

Here's my workaround, it adds one function and one import to the buid task. It copies the other resources (which are not .js , .css and .html) to a folder with the same name as the dependency name. IMO - this is what aurelia-cli should do by default, no runtime support necessary.

Edit: added @patriktornros fixes, this is in TypeScript, if you are translating this to JS - be careful with the closure scope inside the .pipe( rename(

aurelia_project/tasks/build.ts

import * as gulp from 'gulp';
import transpile from './transpile';
import processMarkup from './process-markup';
import processCSS from './process-css';
import {build} from 'aurelia-cli';
import * as project from '../aurelia.json';
import * as rename from 'gulp-rename';

export default gulp.series(
  copyOtherResources,
  readProjectConfiguration,
  gulp.parallel(
    transpile,
    processMarkup,
    processCSS
  ),
  writeBundles
);

function copyOtherResources(done){
  let stream,
    bundle = project.build.bundles.find(function(bundle){return bundle.name==="vendor-bundle.js";});
  for( let i=0; i<bundle.dependencies.length; i++ ){
    let dependency = bundle.dependencies[i],
      collectedResources = [];
    if( dependency.path && dependency.resources ){
      let path = dependency.path.replace("../","./");
      for( let n=0; n<dependency.resources.length; n++ ){
        let resource = dependency.resources[n],
          ext = resource.substr(resource.lastIndexOf('.') + 1);
        if( ext!=='js' && ext!='css' && ext!='html' && ext!=='less' && ext!='scss'){
          collectedResources.push(path+resource)
          dependency.resources.splice(n, 1);
          n--;
        }
      }
      if( collectedResources.length ){
        let s = gulp.src( collectedResources, {passthrough: true, base: path} )
          .pipe( rename( function(path){path.dirname = dependency.name +'/'+ path.dirname;return path;} ));
        stream = stream?stream.pipe(s):s;
      }
    }
  }
  if( stream )
    stream.pipe(gulp.dest('.'));
  done();
}

function readProjectConfiguration() {
  return build.src(project);
}

function writeBundles() {
  return build.dest();
}

The required dependencies are specified in aurelia.json like this:

"prepend": ["node_modules/jquery/dist/jquery.js"],
"dependencies": [
      {
        "name":"lib/semantic",
        "path":"../semantic/dist/",
        "main":"semantic",
        "exports": "$",
        "resources":["semantic.css","themes/default/assets/fonts/icons.woff2"]
      }
]

, I use prepend as a workaround for issue #257

The above code would have been much more simple and easy to implement if the aurelia-cli build code did not rename the extension for non-html/css/js resources to .js Also it would be nice to have a destination property for the dependency, where the files will be copied, the code above is using the name for this purpose.

patriktornros commented 8 years ago

@geleto cant get the dependency.name into the pipe rename?

geleto commented 8 years ago

@patriktornros , check if every object in the dependencies array (in aurelia.json, app bundle) has a name property: { "name":"lib/semantic", "path":"../semantic/dist/", "main":"semantic", "exports": "$", "resources":["semantic.css","themes/default/assets/fonts/icons.woff"] }

If yes - put this line console.log("Dependency: "+JSON.stringify(dependency)); before path.dirname= and check the output:

patriktornros commented 8 years ago

@geleto needed to change

  1. appBundle = project.build.bundles.find(function(bundle){return bundle.name==="vendor-bundle.js";});
  2. added this for empty resources if(dependency.resources==undefined){ continue; }
  3. added a / to collectionResources push
  4. added var test1 = dependency.name; to fix the closure scope

BUT still the browser is looking for a .wof.js looks ok in the rename function !!!?

geleto commented 8 years ago

@patriktornros 1&2 are ok, 3 might be needed if your paths do not end with / I don't think 4 will fix the closure scope, unless you use another function to declare a new scope, to fix it just use 'let' to declare dependency: let dependency = appBundle.dependencies[i] I have updated the code in my initial post.

The runtime should not try to load the resource at all - because we remove it ( see dependency.resources.splice(n, 1) ). The only place where your browser should be looking for the woff file is in the font-face declaration from your library css:

Call console.log( JSON.stringify( appBundle, null, " " ) ); before done() to make sure that all dependencies that do not start with css/js/html/less/scss have been removed from the configuration. Make sure copyOtherResources is before readProjectConfiguration.

oswaldofreitas commented 8 years ago

Please, address this. I'm new to Aurelia and am trying to use uikit, but same with fonts. As a newbie, I dont know how to apply the workahound.

DexterHaslem commented 8 years ago

In case it's unclear, here is all the steps for the easiest (manual) way to get bootstrap working. Use the same settings as the readme in aurelia CLI covers for aurelia.json dependencies section (here also including the theme css):

"dependencies": [

     "jquery",
      {
        "name": "bootstrap",
        "path": "../node_modules/bootstrap/dist",
        "main": "js/bootstrap.min",
        "deps": ["jquery"], "exports": "$", "resources": [
          "css/bootstrap.css",
          "css/bootstrap-theme.css"]
      },

In the component you use bootstrap use the following require

<require from="bootstrap/css/bootstrap.css"></require>

then copy node_modules/bootstrap/dist/fonts into the root of your project. Then fonts will load. This would require you to deploy the following files and folders to a server:

JayDi85 commented 7 years ago

Solution example: https://github.com/aurelia-ui-toolkits/aurelia-materialize-bridge/issues/284#issuecomment-250112393 (and link to SO).

Download files:

Copy files:

Add new prepare-font-glyphicons.js in tasks folder with code:

import gulp from 'gulp';
import merge from 'merge-stream';
import changedInPlace from 'gulp-changed-in-place';
import project from '../aurelia.json';

export default function prepareFontGlyphicons() {

  let source = 'src';

  let taskCss = gulp.src(`${source}\\css\\font-glyphicons.css`)
    .pipe(changedInPlace({firstPass:true}))
    .pipe(gulp.dest(`${project.platform.output}\\css`));

  let taskFonts = gulp.src(`${source}\\fonts\\*`)
    .pipe(changedInPlace({firstPass:true}))
    .pipe(gulp.dest(`${project.platform.output}\\fonts`));

  return merge(taskCss, taskFonts);
}

Edit \tasks\build.js and add following lines:

import prepareFontGlyphicons from './prepare-font-glyphicons'; // <<<<<<<<<<

export default gulp.series(
  readProjectConfiguration,
  gulp.parallel(
    transpile,
    processMarkup,
    processCSS,
    // my tasks
    prepareFontGlyphicons // <<<<<<<<<<
  ),
  writeBundles
);

Add in index.html line: <link rel="stylesheet" href="scripts/css/font-glyphicons.css">

3cp commented 7 years ago

Maybe I missed some lines, but someone should have pointed out trying to bundle font/image inside requirejs bundle would not solve this issue.

What you put in bundle is only visible to requirejs. When a browser sees a css file requesting a font or image resource, it would not use JavaScript require(...) to get it.

Those font files must be copied out as @JayDi85 showed. Maybe aurelia.json can make the task generic and easier.

MannikJ commented 7 years ago

I also find this one very crucial. I'm quite new to all this Javascript building and bundling and often struggeling even with simple tasks like including a css framework. This can get really annoying - especially because the actual programming with aurelia is so easy and you are just held up from doing the funny stuff ;)

To make life easier I adapted @geleto's approach so I can continue building my app a bit more conveniently. Although this is definitely just a very hacky workaround, others might benefit from it as well, so I added it to the end of this post. It adds the copied resource folders to .gitignore in order to avoid committing them unintendedly. I also rewrote the copying part, because sometimes things went wrong an folders where nested incorrectly.

For the future there should be a dedicated location for these additional resources that could be excluded from the repository and deployed to the server, but I have not been able to figure that out, because the modules expect their resources to be located in a specific path. The artistry for people more versatile than me would be to come up with a build-in but flexible system to manage resources of all types.

My aurelia.json (note this is also Typescript):

import * as gulp from 'gulp';
import transpile from './transpile';
import processMarkup from './process-markup';
import processCSS from './process-css';
import { build } from 'aurelia-cli';
import * as project from '../aurelia.json';
import * as fs from 'fs';
import * as readline from 'readline';
import * as os from 'os';

export default gulp.series(
  copyAdditionalResources,
  readProjectConfiguration,
  gulp.parallel(
    transpile,
    processMarkup,
    processCSS
  ),
  writeBundles
);

function copyAdditionalResources(done){
  readGitIgnore();
  done();
}

function readGitIgnore() {
  let lineReader = readline.createInterface({
    input: fs.createReadStream('./.gitignore')
  });
  let gitignore: Array<String> = [];

  lineReader.on('line', (line) => {
    gitignore.push(line);
  });

  lineReader.on('close', (err) => {
    copyFiles(gitignore);
  })
}

function copyFiles(gitignore: Array<String>) {
  let stream,
    bundle = project.build.bundles.find(function (bundle) {
      return bundle.name === "vendor-bundle.js";
    });

  // iterate over all dependencies specified in aurelia.json
  for (let i = 0; i < bundle.dependencies.length; i++) {
    let dependency = bundle.dependencies[i];
    let collectedResources = [];
    if (dependency.path && dependency.resources) {
      // run over resources array of each dependency
      for (let n = 0; n < dependency.resources.length; n++) {
        let resource = dependency.resources[n];
        let ext = resource.substr(resource.lastIndexOf('.') + 1);
        // only copy resources that are not managed by aurelia-cli
        if (ext !== 'js' && ext != 'css' && ext != 'html' && ext !== 'less' && ext != 'scss') {
          collectedResources.push(resource);
          dependency.resources.splice(n, 1);
          n--;
        }
      }
      if (collectedResources.length) {
        if (gitignore.indexOf(dependency.name)< 0) {
          console.log('Adding line to .gitignore:', dependency.name);
          fs.appendFile('./.gitignore', os.EOL + dependency.name, (err) => { if (err) { console.log(err) } });
        }

        for (let m = 0; m < collectedResources.length; m++) {
          let currentResource = collectedResources[m];
          if (currentResource.charAt(0) != '/') {
            currentResource = '/' + currentResource;
          }
          let path = dependency.path.replace("../", "./");
          let sourceFile = path + currentResource;
          let destPath = './' + dependency.name + currentResource.slice(0, currentResource.lastIndexOf('/'));
          console.log('Copying resource', sourceFile, 'to', destPath);
          // copy files
          gulp.src(sourceFile)
            .pipe(gulp.dest(destPath));
        }
      }
    }
  }
}

function readProjectConfiguration() {
  return build.src(project);
}

function writeBundles() {
  return build.dest();
}
EisenbergEffect commented 7 years ago

The best way to handle CSS frameworks is usually to do the same thing you've always done before. Just add a link tag to the page. That's the way they are designed to be used and sometimes you need them loaded before the app anyway.

MannikJ commented 7 years ago

@EisenbergEffect I get your point for the specific case of a bulky CSS framework like bootstrap from which you will probably only use one per app, but I also think you're overlooking the actual problem. It's not really about how you include those resources in your app in the end. Whether you add a link, script, require or whatever tag to the page, or import it into your Javascript doesn't really matter. That's a question of personal taste. It's more about finding a comprehensible concept for the whole build, bundle and deployment process, copying files to correct locations and all those things. Of course, it's not a lot of work to care for some of the essential dependencies on your own, but it should be desired to automate these processes as much and as well as possible to avoid mistakes and increase productivity. In the most cases those dependencies are installed with a package manager from some kind of external repository anyway. This is the basis to treat them similar like you are already doing with Javascript dependencies. I don't get why I should copy them manually and probably break the whole app because of a wrong versioned path in some hidden place of the program. Not to forget, that for the case of a CSS framework, the Aurelia CLI docs actually make you believe that everything will work fine if you just add it to the aurelia.json file, which is simply not true. You must consider, that things that might be absolutely trivial for you as an renowned expert, might not be for beginners or even average web developers. Therefore I find those things should be weighted even heavier than new features for the framework itself. As far as I understand your philosophy and the philosophy of Aurelia as a platform has always been to take everyone on the boat, no matter of the level of experience.

P.S.: Don't get me wrong and please don't be offended. I know you're juggling many balls at once and I highly appreciate the work with Aurelia. Also, English is not my first language, so there might be a lack of sensitivity in some places ;) Your comment just read as if there was no interest to take care of these things at all, that's why I felt I had to write an answer.

EisenbergEffect commented 7 years ago

Of course there is interest in addressing this. However, it's lower priority than other things on the list for the CLI, in part because a simple link tag will fix the problem and is much easier than the work we would have to do to solve this inside the CLI.

codenamezjames commented 7 years ago

Thanks for the workaround @MannikJ Here is the ES6 version of MannikJ's fix.

import gulp from 'gulp';
import transpile from './transpile';
import processMarkup from './process-markup';
import processCSS from './process-css';
import { build } from 'aurelia-cli';
import project from '../aurelia.json';
import fs from 'fs';
import readline from 'readline';
import os from 'os';

export default gulp.series(
  copyAdditionalResources,
  readProjectConfiguration,
  gulp.parallel(
    transpile,
    processMarkup,
    processCSS
  ),
  writeBundles
);

function copyAdditionalResources(done){
  readGitIgnore();
  done();
}

function readGitIgnore() {
  let lineReader = readline.createInterface({
    input: fs.createReadStream('./.gitignore')
  });
  let gitignore = [];

  lineReader.on('line', (line) => {
    gitignore.push(line);
  });

  lineReader.on('close', (err) => {
    copyFiles(gitignore);
  })
}

function copyFiles(gitignore) {
  let stream,
    bundle = project.build.bundles.find(function (bundle) {
      return bundle.name === "vendor-bundle.js";
    });

  // iterate over all dependencies specified in aurelia.json
  for (let i = 0; i < bundle.dependencies.length; i++) {
    let dependency = bundle.dependencies[i];
    let collectedResources = [];
    if (dependency.path && dependency.resources) {
      // run over resources array of each dependency
      for (let n = 0; n < dependency.resources.length; n++) {
        let resource = dependency.resources[n];
        let ext = resource.substr(resource.lastIndexOf('.') + 1);
        // only copy resources that are not managed by aurelia-cli
        if (ext !== 'js' && ext != 'css' && ext != 'html' && ext !== 'less' && ext != 'scss') {
          collectedResources.push(resource);
          dependency.resources.splice(n, 1);
          n--;
        }
      }
      if (collectedResources.length) {
        if (gitignore.indexOf(dependency.name)< 0) {
          console.log('Adding line to .gitignore:', dependency.name);
          fs.appendFile('./.gitignore', os.EOL + dependency.name, (err) => { if (err) { console.log(err) } });
        }

        for (let m = 0; m < collectedResources.length; m++) {
          let currentResource = collectedResources[m];
          if (currentResource.charAt(0) != '/') {
            currentResource = '/' + currentResource;
          }
          let path = dependency.path.replace("../", "./");
          let sourceFile = path + currentResource;
          let destPath = './' + dependency.name + currentResource.slice(0, currentResource.lastIndexOf('/'));
          console.log('Copying resource', sourceFile, 'to', destPath);
          // copy files
          gulp.src(sourceFile)
            .pipe(gulp.dest(destPath));
        }
      }
    }
  }
}

function readProjectConfiguration() {
  return build.src(project);
}

function writeBundles() {
  return build.dest();
}

This code runs successfully with the fowling config in aurlia.json

...
{
    "name": "font-awesome",
    "main":"",
    "path": "../node_modules/font-awesome",
    "resources": [
        "css/font-awesome.css",
        "/fonts/fontawesome-webfont.woff2",
        "/fonts/FontAwesome.otf",
        "/fonts/fontawesome-webfont.eot",
        "/fonts/fontawesome-webfont.svg",
        "/fonts/fontawesome-webfont.ttf"
    ]
}
...

http://stackoverflow.com/questions/39271458/how-can-i-add-font-awesome-to-my-aurelia-project-using-npm/41236851#41236851

fabioluz commented 7 years ago

This issue can now be solved by adding a copy instruction in the aurelia.json.

aurelia.json - valid if the project was created by aurelia-cli 0.25.0 or greater

"bundles": [ ... ], 
 "copyFiles": {
    "node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2": "bootstrap/fonts"
    "node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff": "bootstrap/fonts",
    "node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf": "bootstrap/fonts"
  }

If the project was created by an older CLI version, you will have to create the copy task inside the tasks folder -> https://github.com/aurelia/cli/blob/master/lib/resources/tasks/copy-files.js. After that, call the copy task in the build.js/ts task -> https://github.com/aurelia/cli/blob/master/lib/resources/tasks/build.js#L15

@EisenbergEffect I think you can close this issue.

pbrickell commented 7 years ago

I'm using 0.26.1. It already has a copy-files.ts that is called in build.ts. How do I make it work in this case?

fabioluz commented 7 years ago

@pbrickell Add the following lines in aurelia.json, after the bundles property:`

"bundles": [ ... ], 
 "copyFiles": {
    "node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2": "bootstrap/fonts"
    "node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff": "bootstrap/fonts",
    "node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf": "bootstrap/fonts"
  }

Run the application again.

pbrickell commented 7 years ago

@fabioluz That didn't work for me. The following did though

"bundles": [ ... ], "copyFiles": { "./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2": "./fonts", "./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff": "./fonts", "./node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf": "./fonts" }

fabioluz commented 7 years ago

@pbrickell Are you sure the fonts folder hasn't been created? I tried here in a brand new project and it worked. Also, why are you using ./fonts? Shouldn't it be ./bootstrap/fonts?

pbrickell commented 7 years ago

@fabioluz

With your original I ended up with a bootstrap/fonts folder at the same level as src but in the browser I was seeing 401 errors for http://ei16.ei.lan:9000/fonts/glyphicons-halflings-regular.* Seeing this I changed my target to match, hence "./fonts". It then works.

I think this may stem from how I am handling my bootstrap.css. To get the bootstrap.css loaded I have copied it to src/bootstrap.scss and required it with <require from="./bootstrap.css"></require>

I don't know if that is idiomatic. It was the only way I get the css loaded at all.

fabioluz commented 7 years ago

@pbrickell Try to load bootstrap as described in the http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/the-aurelia-cli/10. I'm pretty sure it will work :)

pbrickell commented 7 years ago

I get 404 for that url.

pbrickell commented 7 years ago

I found the item in the docs. That's exactly what I have in my aurelia.json

pbrickell commented 7 years ago

This conversation may be relevant https://gitter.im/aurelia/Discuss?at=58c01140de504908226068e7

fabioluz commented 7 years ago

@pbrickell ping me on gitter channel. I can help you better there.

pbrickell commented 7 years ago

A final note, Thanks to Fabio for all the help.

Turns out bootstrap requires jquery and for jquery to be appear before bootstrap in aurelia.json.

After fixing that everything works perfectly according Fabio's here https://github.com/aurelia/cli/issues/248#issuecomment-285447958