Angular-cli: Can't build to parent outDir folder with 1.5.4

Created on 23 Nov 2017  路  32Comments  路  Source: angular/angular-cli

Versions

Angular CLI: 1.5.4
Node: 6.11.2
OS: win32 x64 (Win10)
Angular: 4.4.6
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-webworker
... platform-webworker-dynamic, router, tsc-wrapped

@angular/cdk: 2.0.0-beta.12
@angular/cli: 1.5.4
@angular/material: 2.0.0-beta.12
@angular-devkit/build-optimizer: 0.0.33
@angular-devkit/core: 0.0.21
@angular-devkit/schematics: 0.0.37
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.4
@schematics/angular: 0.1.7
typescript: 2.3.4
webpack: 3.8.1

Repro steps

  • Set apps[0].outDir as "../dist" on .angular-cli.json
  • run ng b

Observed behavior

Only a error message: An asset cannot be written to a location outside the project.

Desired behavior

Build the project without problem.

Mention any other details that might be useful (optional)

We have tried to add allowOutsideDir to ours assets configuration on cli config, but doesn't work. Is this the expected behaviour? I don't found related information about it in de64b86 or #8122 :(

investigation

Most helpful comment

Same problem here.
I can't believe a major functionality of the CLI, "ng b", doesn't work after an update...
Downgrade to 1.5.3...

All 32 comments

Same problem here.
I can't believe a major functionality of the CLI, "ng b", doesn't work after an update...
Downgrade to 1.5.3...

@hansl can you have a look please?

@hansl @filipesilva @rbluethl: This issue is occuring when the outdir in .angular-cli.json is outside the angular folder. (eg. "outDir": "../../bin/Debug/www")

@hansl @filipesilva : Same issue here. Please fix the issue.

".angular-cli.json" Config
...
"apps": [
{
"root": "src",
"outDir": "../web/src/main/resources/static",
"assets": [
...

On Build
>ng build
An asset cannot be written to a location outside the project.

Same problem, I'm using the outDir param to build outside my angular root folder.

Same here

Same here

// Prevent asset configurations from writing outside of the output path, except if the user
// specify a configuration flag.
// Also prevent writing outside the project path. That is not overridable.
const fullOutputPath = path.resolve(buildOptions.outputPath, asset.output);
if (!fullOutputPath.startsWith(projectRoot)) {
    const message = 'An asset cannot be written to a location outside the project.';
    throw new SilentError(message);
}

What flag is told about?

@gvart I think that the flag is allowOutsideOutDir in the last section.

Same problem

I think allowOutsideOutDir applies to asset copying - is this not different to build destination?

ya, something wrong when build.

{
      "root": "src",
      "outDir": "../../../target/frontend",
      "assets": [
        {
          "glob": "**/*",
          "input": "./assets/",
          "output": "../../../target/frontend",
          "allowOutsideOutDir": true
        }
      ],
...}

I'm not sure this covers every possible scenario, but the obvious thing to do is use an npm script to copy things post-build

package,json

  "scripts": {
    ...
    "build-prod": "ng build --prod --stats-json",
    "postbuild-prod": "copyfiles ./dist/**/* c:/dist",
  },

Footnote - 'postbuild-prod' runs automatically after 'build-prod'.



This is quoted from issue 8122, and seems fair enough as a precaution.

This is done so that people don't overwrite their app by mistake (or a malicious app overwrites system files).

So, requiring the developer to specifically copy via script achieves both objectives.

And what about the --watch option ?

Patching the 1.5.4 with fix in #8630 solve the problem, so just wait for the next release.

oh man...

Does the merge also make ng serve work? The flag makes ng build work, but not the serve command yet. This was a rather bad error on Angular's part, it's very often neccesary for testing purposes to access dirs outside the ng cli project home dir, i.e. images, etc.

...same problem here, what about ng serve guys? ... 馃檨

8630 solves the problem. Until the fix is released, it's better to lock the cli version at 1.5.3.

Damn, no wonder, I was like, it was working at work before the weekend, why is it not working at home?

I was scratching my head so much I am almost bald now.

I'm glad this is being fixed. I prevent my destination folder from being deleted by the CLI with the new "no-delete-output-path" option. Not a problem.

"start": "ng serve --proxy-config proxy.conf.json --no-delete-output-path",
"build": "ng build --watch --no-delete-output-path",

Is there anybody who can help me understand how can I use the fix #8630 ?

@djpysu They don't seem to want to fix it properly, so I have had to edit the angular/cli dist myself. It is odd how the team have been so slow on this, it is usually necessary to have a "common-assets" dir that several ui services can access such that you don't have the same "favicon.ico" or "logo.png" file copied X times.

What is interesting is that with the boolean flag set ("allowOutsideOutDir": true) on a particular asset, it normally makes ng build work but still not ng serve. You can search the angular/cli code and actually see the line that makes the cli throw the error for ng serve. I simply commented out the one single line that calls throw() and presto, I got ng serve working as normal again with external assets.

Not sure why they implemented this to be frank. It isn't a security feature like they say because if a nefarious actor has compromised your system to such a degree that they can run your app straight off the bat, they sure can easily do what I just did and make ng serve work. I could be wrong though...

@djpysu the fix was released with v1.5.5... I personally doesn't remember to do some changes in my configs to get work... Which version r u using?

Yeah, I also thought that. I updated to 1.6.4 - not working, back to 1.5.3 - not working. Only with 1.4.1 is working for me. I think I'm doing something wrong.

can u share ur config and error message?

Same error message like everybody: An asset cannot be written to a location outside the project.

From angular-cli.json

  "apps": [
    {
      "root": "src",
      "outDir": "../../../public/dist/",
      "deployUrl": "/dist/",
      "allowOutsideOutDir": true,
      "disablePathCheck":true,
      "assets": [{
          "glob": "**/*",
          "input": "./assets/",
          "output": "../assets/",
          "allowOutsideOutDir": true
      }, {
          "glob": "favicon.ico",
          "input": "./",
          "output": "./",
          "allowOutsideOutDir": true
      }],
      "index": "index.html",
      "main": "main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "app/core/preloader/preloader.scss",
        "styles.scss"
      ],
      "scripts": [
        "../node_modules/jquery/dist/jquery.js",
        "../node_modules/chart.js/dist/Chart.min.js",
        "app/core/preloader/preloader.js"
      ],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],

package.json

"scripts": {
    "ng": "ng",
    "install": "napa",
    "start": "ng serve",
    "build": "ng build --watch",
    "test": "ng test",
    "lint": "ng lint",
    "modernizr": "modernizr -c modernizr-config.json -d src/modernizr.js",
    "postinstall": "node ./node_modules/protractor/bin/webdriver-manager update",
    "e2e": "ng e2e"
  },
  "private": true,
  "napa": {
    "jquery.flot.spline": "miloszfalinski/jquery.flot.spline",
    "ika.jvectormap": "kakirigi/ika.jvectormap"
  },
  "dependencies": {
    "@agm/core": "1.0.0-beta.0",
    "@angular/animations": "^5.2.0",
    "@angular/cli": "^1.6.4",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/platform-server": "^5.2.0",
    "@angular/router": "^5.2.0",
    "@ngx-translate/core": "8.0.0",
    "@ngx-translate/http-loader": "0.0.3",
    "@swimlane/ngx-charts": "^6.1.0",
    "@swimlane/ngx-datatable": "^11.1.7",
    "Flot": "github:flot/flot#v0.8.3",
    "ag-grid": "9.0.3",
    "ag-grid-angular": "9.0.3",
    "angular-tree-component": "3.3.0",
    "angular2-datatable": "0.6.0",
    "angular2-text-mask": "8.0.0",
    "angular2-toaster": "3.0.1",
    "bootstrap": "3.3.7",
    "chart.js": "2.5.0",
    "classlist.js": "1.1.20150312",
    "codemirror": "5.25.0",
    "core-js": "2.4.1",
    "d3": "^4.12.2",
    "easy-pie-chart": "2.1.7",
    "flot": "flot/flot#v0.8.3",
    "fullcalendar": "3.3.1",
    "intl": "1.2.5",
    "jqcloud2": "2.0.2",
    "jquery": "3.2.1",
    "jquery-slimscroll": "1.3.8",
    "jquery-sparkline": "2.4.0",
    "jquery.browser": "0.1.0",
    "jquery.flot.tooltip": "github:krzysu/flot.tooltip",
    "lodash": "4.17.4",
    "modernizr": "3.5.0",
    "moment": "2.18.1",
    "mydaterangepicker": "^4.2.0",
    "ng2-charts": "1.5.0",
    "ng2-dnd": "4.0.2",
    "ng2-file-upload": "1.2.1",
    "ng2-img-cropper": "0.8.6",
    "ng2-select": "1.2.0",
    "ng2-table": "1.3.2",
    "ng2-tag-input": "1.0.5",
    "ng2-validation": "4.1.0",
    "ng4-charts": "^1.6.0",
    "ngx-bootstrap": "^2.0.0-beta.8",
    "ngx-color-picker": "4.0.0",
    "ngx-infinite-scroll": "0.4.1",
    "node-sass": "3.13.0",
    "rxjs": "^5.5.6",
    "screenfull": "3.2.0",
    "spinkit": "1.2.5",
    "summernote": "0.8.3",
    "sweetalert": "1.1.3",
    "ts-helpers": "1.1.1",
    "weather-icons": "github:erikflowers/weather-icons",
    "web-animations-js": "2.2.2",
    "zone.js": "0.8.4"
  },
  "devDependencies": {
    "@angular/compiler-cli": "^5.2.0",
    "@types/codemirror": "0.0.38",
    "@types/jasmine": "2.5.38",
    "@types/lodash": "4.14.61",
    "@types/moment": "2.13.0",
    "@types/node": "^6.0.96",
    "codelyzer": "2.0.0",
    "jasmine-core": "2.5.2",
    "jasmine-spec-reporter": "3.2.0",
    "karma": "1.4.1",
    "karma-chrome-launcher": "2.0.0",
    "karma-cli": "1.0.1",
    "karma-coverage-istanbul-reporter": "0.2.0",
    "karma-jasmine": "1.1.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "karma-read-json": "1.1.0",
    "loaders.css": "0.1.2",
    "napa": "2.3.0",
    "protractor": "5.1.0",
    "ts-node": "2.0.0",
    "tslint": "4.5.0",
    "typescript": "^2.5.3",
    "webdriver-manager": "10.2.5"
  }

Same issue with 1.6.3 and 1.6.5 when running 'ng build'

      "assets": [{
        "input": "./assets/",
        "glob": "**/*",
            "output": "../EcView/WebContent/dist/assets",
        "allowOutsideOutDir": true
      }],

An asset cannot be written to a location outside the project.

when will this be fixed ...

@Sanafan You could look into it. It's marked as an easy to fix regression

This error is still occurring in 1.7.4. It's highly problematic for a project I'm working on since I have around 5GB worth of images to serve and placing them in the assets folder causes the ng serve to crash.

For anyone looking to fix it locally, edit ../node_modules/@angular/cli/models/webpack-configs/common.js. The code starts at line 99. I'm not going to make a pull request to fix it because I don't know if there is a legit reason for this functionality (although it seems odd to me and as others have mentioned, it's not really a security thing).

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._

Was this page helpful?
0 / 5 - 0 ratings