Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stylesheet from (npm) linked package not loaded correctly #3500

Closed
weitjong opened this issue Dec 9, 2016 · 27 comments · Fixed by #19713
Closed

Stylesheet from (npm) linked package not loaded correctly #3500

weitjong opened this issue Dec 9, 2016 · 27 comments · Fixed by #19713

Comments

@weitjong
Copy link

weitjong commented Dec 9, 2016

OS

Tested on both Windows 7 and Linux (Fedora 24)

Version

$ ng --version
angular-cli: 1.0.0-beta.22-1
node: 4.6.1
os: linux x64

The app was created using CLI.

Repro steps

  1. Install a package containing a stylesheet (say bootstrap-sass, actually any package will do) globally via npm.
  2. git clone https://github.com/twbs/bootstrap-sass.git into a working directory, cd to that working directory and perform npm link command.
  3. ng new project in another separate directory, cd to the newly create project directory and perform npm link bootstrap-sass. This will create a bootstrap-sass symlink in node_modules pointing to the local git repository.
  4. Modify angular-cli.json to reference the stylesheet in the linked package.
      "styles": [
        "../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss",
        "styles.scss"
      ],
  1. ng serve and observe that styles from bootstrap is not exported correctly in the index page.
  2. ng build and observe that the generated styles.bundle.js does not do "exports.push()".

The log given by the failure

There was no error log, webpack declared the "bundle is now valid".

Mention any other details that might be useful

Using normal npm install approach does not have this issue. i.e. after npm unlink bootstrap-sass && npm install bootstrap-sass then all is fine.

Use case: I have a forked gentelella repository locally to fix some of the issues I found, so I cannot just simply npm install it in my project. Using npm link approach as I outlined above should work. It seems angular-cli (or webpack, I am not sure) is being confused by symlink. As a temporary workaround, I replace the stylesheet reference in the angular-cli.json with an absolute path to the stylesheet file in the local git repo.

@clydin
Copy link
Member

clydin commented Dec 9, 2016

For a cleaner workaround, you can npm install using the path to the forked package.

@weitjong
Copy link
Author

For a cleaner workaround, you can npm install using the path to the forked package.

@clydin Thanks for your reply. The npm install will just install a snapshot of the local repo. This would force me to redo the install each time I make changes in my local repo. With symlink all changes are automatically reflected in my project using the linked package.

I also do not want to just check-in the stylesheet in question into my own project repo and use the @import in the styles.scss as the workaround (although it would also work) because: 1) I don't want to break the linkage with upstream so that I could still easily merge upstream changes; 2) I can also easily contribute back my fixes back to upstream.

@weitjong
Copy link
Author

Using @import "../node_modules/gentelella/src/scss/custom"; in the styles.scss as the workaround now. The sass preprocessor handles the symlink well.

@filipesilva filipesilva added command: build P5 The team acknowledges the request but does not plan to address it, it remains open for discussion type: bug/fix labels Dec 12, 2016
@filipesilva filipesilva self-assigned this Dec 12, 2016
@serhiisol
Copy link
Contributor

CLI doesn't seem to copy anything outside of the src folder, but should be able to copy from node_modules.

To reproduce this weird issue just try to copy file one level up of src folder

@zackarychapple
Copy link
Contributor

zackarychapple commented Dec 13, 2016

@serhiisol it can copy from outside src, in the example repo for #3542 it pulls the styles for buttons but the column styles are not applying.

@serhiisol
Copy link
Contributor

@zackarychapple where is the copy process specified in this repo? angular cli json doesn't have it in example you've provided : https://github.com/zackarychapple/bootstrap-ng2/blob/master/angular-cli.json

@zackarychapple
Copy link
Contributor

@serhiisol I tried @import "../node_modules/bootstrap/scss/bootstrap-flex"; in https://github.com/zackarychapple/bootstrap-ng2/blob/master/src/styles.scss as well as in the angular-cli.json and neither option worked.

@serhiisol
Copy link
Contributor

@zackarychapple but your last comment is opposite to the one before :)

@zackarychapple
Copy link
Contributor

@serhiisol you're right the code I committed was after I removed the line that copied from src.

@zackarychapple
Copy link
Contributor

@hansl is it possible to add the ability to resolve node_modules directly in the sass with something like https://github.com/jtangelder/sass-loader as this issue is fixed?

@filipesilva
Copy link
Contributor

filipesilva commented Dec 22, 2016

Now that #3401 is done, it should be feasible to do something like what was originally requested:

"styles": [
  { "input": "../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss", "output": "bootstrap.css" },
  "styles.scss"
],

Can you see if this solves it?

@weitjong
Copy link
Author

weitjong commented Dec 24, 2016

I have upgraded to angular-cli 1.0.0-beta.24 to test this and modifed my angular-cli.json as you suggested. Still not working if the input file is in a symlink directory. It works only if the input file is in a normal directory.

EDIT: correct typo.

@Splaktar
Copy link
Member

Splaktar commented Jan 2, 2017

@filipesilva As mentioned in this comment the fix only appears to apply to SCSS/CSS/JS, but not to static assets like font files (used by font-awesome, material-design-icons, etc).

Should we open a separate issue for that?

@filipesilva
Copy link
Contributor

@Splaktar this functionality now exists for assets as well.

Closing as outdated. If this is still a problem, please let me know.

@tx-tim
Copy link

tx-tim commented May 30, 2017

@filipesilva Could you provide a reference for implementing this? I'm having a similar issue

@ptmccarthy
Copy link

ptmccarthy commented May 31, 2017

I am also running into this same issue. Whenever I try to add a .css file to my .angular-cli.json from a symlinked directory within node_modules (from npm link), it does not pull it in to the build.

The exact same .css file in a non-symlinked directory gets pulled in just fine, but that does not do me any good.

I tried the solution posted a couple of posts above by @filipesilva but it did not change the behavior.

Edit: Using @require in my application's base .scss file to load the .css file from the linked node_modules folder does allow me to work around for now, but it is not an ideal solution.

@filipesilva
Copy link
Contributor

Reopening as there are reports of this still happening for scss files.

@filipesilva filipesilva reopened this Jun 12, 2017
@filipesilva filipesilva added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent help wanted effort1: easy (hours) and removed P5 The team acknowledges the request but does not plan to address it, it remains open for discussion labels Jun 12, 2017
@umdstu
Copy link

umdstu commented Oct 19, 2018

Greetings! Is there an ETA on this? I recently expanded my project to a second application, with a lot of duplicate node_modules required. So I moved the node_modules directory up one level, and created windows symlinks from each projects' node_modules directory to the node_directory one level up. Seems to be working for the most part except, as indicated in the past, the CSS files aren't being pulled in.

@ngbot ngbot bot added this to the Backlog milestone Jan 24, 2019
@johnbfox
Copy link

I'm also experiencing this. I'm trying to co-develop a css library alongside our application. We store our fonts inside of the css library, so the scss import workaround does not work. ng serve breaks because the CLI looks inside of the app directory for those fonts rather than inside the linked module. Are there any plans to pull this out of the backlog?

@enterframe
Copy link

+1 same here

@cdipiet
Copy link

cdipiet commented Oct 22, 2019

Cannot import css from angular.json if node_modules is a symbolic link.

Hello, I have a similar issue, I have a common node_modules directory that I link in my projects with:
(windows) mklink /J node_modules D:\node_modules
(linux) ln -s ~/node_modules
All seems to work but including css files in node_modules(e.g. "node_modules/bootstrap/dist/css/bootstrap.min.css") to angular.json.
Adding such css to src/style.css by
@import "~bootstrap/dist/css/bootstrap.min.css";
works fine, but I cannot use angular.json to do that.
Deleting node_modules symlink and copying the whole node_modules directory inside the project let angular.json css import from node_modules working again.
So it seems the angular-cli has issues with symbolic links to node_modules.

@rgammans
Copy link

rgammans commented Nov 7, 2019

I hit what I thought was a similar issue and used the shell script below to build and example environment to work in.

#!/bin/bash
#
# ngcli_bug3500.sh
#
# This creates an ng project and add a unit test to which fails
# if @angular/cli issue 3500 is unfixed 
#
#
# (C) Roger Gammans <[email protected]>
# This file can be freely redistributed.

## Comment this out to use an already in scope @Angular/cli installation
npm i @angular/cli

npx ng new cli3500 --defaults
cd cli3500
mkdir foo
cat > foo/test.css <<EOF

.nothere {
    display: none;
}

EOF
ln -s foo bar
mv src/app/app.component.spec.ts src/app/app.component.spec.ts.orig
head -n -1 src/app/app.component.spec.ts.orig > src/app/app.component.spec.ts
cat >> src/app/app.component.spec.ts  << EOF

  it('should render check element invisibly', () => {
    /* This checks the access to the new css ; which should hide it
     */
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('div.nothere').offsetHeight).toBe(0);
  });
});

EOF

cat >> src/app/app.component.html << EOF
<div class="nothere">Some texts this is any.</div>
EOF

## Add './bar/test.css' to angular json
#  first write out a node script to
#  do the change then execute it.
cat > mod_ng_json.js <<EOF
'use strict';

function do_append(ary, value) {
    ary[ary.length] = value
}

const fs = require('fs');

// Read in angular.json
let rawdata = fs.readFileSync('angular.json.bak');
let cli_conf= JSON.parse(rawdata);

// Change it and write it out
do_append(cli_conf["projects"]["cli3500"]["architect"]["build"]["options"]["styles"],"./bar/test.css")
do_append(cli_conf["projects"]["cli3500"]["architect"]["test"]["options"]["styles"],"./bar/test.css")

fs.writeFileSync('angular.json',JSON.stringify(cli_conf,null,2));

EOF
mv angular.json angular.json.bak
nodejs mod_ng_json.js

#Run the app tests (one should fail if this bug is not fixed)
npx ng test

Using the created app I tracked the fact the the stylesheets where being loaded by webpack, but by their canonical absolute path.

This (eventually) lead me to looking at webpack bugs and I found this , webpack/webpack#8824 , which then lead me to the webpack resolveSymlink option.

With a bit more digging I can make the test project I generated pass the tests by changing the options for the test command in angular.json (and other commands will need it as well) to add

        "test": {
          "options": {
            "preserveSymlinks": true,
           ...
         }
  }

It appears there might be some downside of symlink paths not being watched correctly with this option, and the webpack bug does suggest the issue could also be fixed by adding an extra reference to absolute canonical path to the webpack loader spec as well as the path 'through' the symlink.

Hope this help..

@s4m0r4m4
Copy link

s4m0r4m4 commented Feb 12, 2020

I think I've also run into something related to this:
in the "styles" section of angular.json, if I include a CSS file that is actually a symlink, angular builds the project OK and includes that symlinked CSS file, but if I make a change in the targeted CSS file, angular does not pick up the change and reload the new style.

Steps:

  • Create a new angular project, ng new
  • Take a CSS file that I'd like to share between angular projects, say "mystyle.scss".
  • I keep the file in a shared location and then symlink it within each angular project and then point to the symlinked version in angular.json.
  • Angular correctly builds & serves the app using "ng serve" (good!)
  • Make a change to mystyle.scss
  • Angular does not reload styles after this change or any subsequent change.
  • If I replace the symlinked version with the actual file, angular notices changes in that file and reloads the styles appropriately.
  • I also have "preserveSymlinks"=true in angular.json and tsconfig.json.

@Mayocampo
Copy link

Still hapenning in this date. I just changed from NPM to PNPM (which apparently creates symlink for node_modules folder). Now none of my recently "migrated" projects are loading styles... No SCSS for me, just plain old CSS.

Any idea on when are we gonna have solution for this? And any temporary workaround? A good one?

@alan-agius4 alan-agius4 removed the freq1: low Only reported by a handful of users who observe it rarely label Jan 5, 2021
@ngbot ngbot bot modified the milestones: Backlog, needsTriage Jan 5, 2021
@alan-agius4 alan-agius4 removed this from the needsTriage milestone Jan 5, 2021
@ngbot ngbot bot added this to the needsTriage milestone Jan 5, 2021
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Jan 5, 2021
filipesilva pushed a commit that referenced this issue Jan 6, 2021
…l styles entrypoints

With this change we resolve the global stylesheet entrypoint path to use the realpath instead of the symlink path.

Fixes #3500
filipesilva pushed a commit that referenced this issue Jan 6, 2021
…l styles entrypoints

With this change we resolve the global stylesheet entrypoint path to use the realpath instead of the symlink path.

Fixes #3500

(cherry picked from commit 1df8a3d)
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.