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

less-loader break change and cause error in @angular/cli 6.0 #10430

Closed
vthinkxie opened this issue Apr 23, 2018 · 16 comments · Fixed by #11958
Closed

less-loader break change and cause error in @angular/cli 6.0 #10430

vthinkxie opened this issue Apr 23, 2018 · 16 comments · Fixed by #11958

Comments

@vthinkxie
Copy link

vthinkxie commented Apr 23, 2018

Versions

Angular CLI: 6.0.0
Node: 8.10.0
OS: darwin x64
Angular: 5.2.9
... animations, common, compiler, core, forms, http
... platform-browser, platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.5.7
@angular-devkit/build-angular     0.5.7
@angular-devkit/build-optimizer   0.5.7
@angular-devkit/core              0.5.7
@angular-devkit/schematics        0.5.7
@angular/cdk                      5.2.4
@angular/cli                      6.0.0-rc.5
@angular/compiler-cli             5.2.10
@angular/language-service         5.2.10
@ngtools/json-schema              1.1.0
@ngtools/webpack                  6.0.0-rc.5
@schematics/angular               0.5.7
@schematics/update                0.5.7
rxjs                              5.5.2
typescript                        2.4.2
webpack                           4.5.0

Repro steps

  • Step 1
    install @angular/cli 6.0 version

  • Step 2
    run ng new next-cli --style=less

  • Step 3
    copy the follow less code and paste it into style.less

.bezierEasingMixin() {
  @functions: ~`(function() {
  var NEWTON_ITERATIONS = 4;
  var NEWTON_MIN_SLOPE = 0.001;
  var SUBDIVISION_PRECISION = 0.0000001;
  var SUBDIVISION_MAX_ITERATIONS = 10;

  var kSplineTableSize = 11;
  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);

  var float32ArraySupported = typeof Float32Array === 'function';

  function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
  function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
  function C (aA1)      { return 3.0 * aA1; }

  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
  function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }

  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
  function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }

  function binarySubdivide (aX, aA, aB, mX1, mX2) {
    var currentX, currentT, i = 0;
    do {
      currentT = aA + (aB - aA) / 2.0;
      currentX = calcBezier(currentT, mX1, mX2) - aX;
      if (currentX > 0.0) {
        aB = currentT;
      } else {
        aA = currentT;
      }
    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
    return currentT;
  }

  function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
   for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
     var currentSlope = getSlope(aGuessT, mX1, mX2);
     if (currentSlope === 0.0) {
       return aGuessT;
     }
     var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
     aGuessT -= currentX / currentSlope;
   }
   return aGuessT;
  }

  var BezierEasing = function (mX1, mY1, mX2, mY2) {
    if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
      throw new Error('bezier x values must be in [0, 1] range');
    }

    // Precompute samples table
    var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
    if (mX1 !== mY1 || mX2 !== mY2) {
      for (var i = 0; i < kSplineTableSize; ++i) {
        sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
      }
    }

    function getTForX (aX) {
      var intervalStart = 0.0;
      var currentSample = 1;
      var lastSample = kSplineTableSize - 1;

      for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
        intervalStart += kSampleStepSize;
      }
      --currentSample;

      // Interpolate to provide an initial guess for t
      var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
      var guessForT = intervalStart + dist * kSampleStepSize;

      var initialSlope = getSlope(guessForT, mX1, mX2);
      if (initialSlope >= NEWTON_MIN_SLOPE) {
        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
      } else if (initialSlope === 0.0) {
        return guessForT;
      } else {
        return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
      }
    }

    return function BezierEasing (x) {
      if (mX1 === mY1 && mX2 === mY2) {
        return x; // linear
      }
      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
      if (x === 0) {
        return 0;
      }
      if (x === 1) {
        return 1;
      }
      return calcBezier(getTForX(x), mY1, mY2);
    };
  };

  this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18);
  // less 3 requires a return
  return '';
})()`;
}
// It is hacky way to make this function will be compiled preferentially by less
// resolve error: `ReferenceError: colorPalette is not defined`
.bezierEasingMixin();
  • Step 4
    run ng serve

Observed behavior

the less inline javascript works error in @angular/cli 6.0 version

Inline JavaScript is not enabled. Is it set in your options?
      in /Users/Documents/next-cli/src/styles.less (line 110, column 0)

it works well in @angular/cli 1.x version

Desired behavior

make less-loader work fine as before in 6.0 version
or provide configuration to set less options in angular.json

Mention any other details that might be useful (optional)

add { javascriptEnabled: true } here can make it works again.

https://github.com/angular/devkit/blob/3d809ef29cf690f9d2b37fa048710132a7a9e389/packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/styles.ts#L203

@vthinkxie vthinkxie changed the title less javascriptEnabled break change and error in @angular/cli 6.0 less-loader javascriptEnabled break change and cause error in @angular/cli 6.0 Apr 23, 2018
@vthinkxie vthinkxie changed the title less-loader javascriptEnabled break change and cause error in @angular/cli 6.0 less-loader break change and cause error in @angular/cli 6.0 Apr 23, 2018
@ppjjzz
Copy link

ppjjzz commented May 4, 2018

the same issues

@vthinkxie
Copy link
Author

vthinkxie commented May 7, 2018

Hi @filipesilva , any update on this issue? it still not work on latest version of angular-cli
thanks.

@lyon-liao
Copy link

the same issues

@clydin
Copy link
Member

clydin commented May 8, 2018

According the the less.js documentation, inline javascript support has been deprecated and disabled by default due to the potential for security issues. The recommended approach is to now use the @plugin at-rule described here: http://lesscss.org/features/#plugin-atrules-feature

@vthinkxie
Copy link
Author

@clydin yes, but the angular cli does not provide config for less-loader yet, it will block users to upgrade to it since less file will no longer work now.

@iwe7
Copy link

iwe7 commented May 14, 2018

the same issue

@filipesilva
Copy link
Contributor

We strive to keep our dependencies up to date and in the case of Less, we do defer to their deprecation policy.

The @plugin approach looks like a viable alternative for projects that need to use inline javascript and as far as I can tell works today with no changes to Angular CLI.

I tried following the example @clydin linked to:

// src/styles.less
@plugin "my-plugin";

.show-me-pi {
  value: pi();
}
// src/my-plugin.js
registerPlugin({
  install: function (less, pluginManager, functions) {
    functions.add('pi', function () {
      return Math.PI;
    });
  }
})

Then I ran ng build --extract-css and this is what I saw in the output:

// dist/styles.css
.show-me-pi {
  value: 3.141592653589793;
}

So it seems like the function is being loaded and works.

If using @plugin does not work for your use case let me know so we can reopen the discussion.

@vthinkxie
Copy link
Author

vthinkxie commented May 21, 2018

@filipesilva
yes, the @plugin works well, but all the ant design (https://github.com/ant-design/ant-design) design system are based on javascript in less (which more than 10,000 lines of less code and can not be changed into @plugin right away).
The react version of ant design can work with less option in webpack configuration file, but in angular version which most users work with @angular/cli, we can do noting with less configuration.

We can not change less file since we must sync it with react version, and we can not config less config because @angular/cli does not provide it now.
Thanks for your response any way.

@filipesilva
Copy link
Contributor

@vthinkxie I see how that is problematic on your side. Let me reopen to discuss further. Will bring it up with the team.

@filipesilva filipesilva reopened this May 21, 2018
@vthinkxie
Copy link
Author

@filipesilva Thanks!

@filipesilva filipesilva added comp: cli/build needs: discussion On the agenda for team meeting to determine next steps labels May 21, 2018
@haxiha
Copy link

haxiha commented May 23, 2018

hi @filipesilva maybe @vthinkxie is right. ng cli should be more simple and configurable, adaptable to different pro, there are a thousand pro in a thousand developer's way, as a thousand hamlets in a thousand people's eyes.

@gozeon
Copy link

gozeon commented May 24, 2018

npm install [email protected] -g
lessc node_modules/ng-zorro-antd/src/ng-zorro-antd.less ./src/styles.css

@yeepZhang
Copy link

anyone keep up with this issue?

@vincentjames501
Copy link
Contributor

Just ran into the same thing. This is a blocker for our upgrade to Angular 6.

@alexeagle
Copy link
Contributor

Sorry, this was unintentional breaking change in Angular 6. We will check if we can easily enable the Less inlineJavascript option so that a 6.x release unblocks you migrating to 6.

However, since this feature is deprecated upstream from us, it will still go away in a future version of Angular CLI when Less no longer supports it.

At that time (or if we determine it's too much effort to fix in Angular 6), we find that it's hard to fix, your options will be:

If you're willing to go off the supported path, it's possible to add a postInstall hook in your package.json that replaces the version of less that's installed by Angular CLI, and then it might continue to work as before.
Make your own webpack config (basically like ng eject usage) and roll your own
Change your .less files to stop using inline JavaScript (and ask libraries you depend on to do the same)

filipesilva added a commit to filipesilva/angular-cli that referenced this issue Aug 21, 2018
JLHwung pushed a commit to easyops-cn/ng-zorro-antd that referenced this issue Nov 16, 2018
angular/angular-cli#10430 has been fixed and shipped since @angular/cli 6.2.0.

It is unecessary to lock less at version 2
JLHwung pushed a commit to easyops-cn/ng-zorro-antd that referenced this issue Nov 17, 2018
angular/angular-cli#10430 has been fixed and shipped since @angular/cli 6.2.0.

It is unecessary to lock less at version 2
@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 Sep 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.