Azure-functions-core-tools: Folder structure changes to support TypeScript

Created on 8 Nov 2018  路  8Comments  路  Source: Azure/azure-functions-core-tools

Proposed folder structure for TS Apps:

FunctionApp
--/src
----/Function1
------index.ts
------function.json
----host.json
----extensions.csproj
--/dist
----/Function1
------index.js
------function.json
----host.json
----package.json
----/node_modules
----/bin
--local.settings.json
--tsconfig.json
--package.json

Here, /src and /dist will be configurable. Above subject to minor change (hopefully with bundling extension.csproj moves to /bin, for instance.)

TypeScript

Most helpful comment

I've been looking at what can be achieved with the code as it currently is and local running/debugging with Typescript and a folder structure similar to above can certainly be done (although there are manual set up steps). As you say, retooling is required to preserve CLI deployment.
See here if you're interested https://github.com/shladdergoo/insult-function/wiki/Debugging-Typescript-Azure-Functions-with-VS-Code

All 8 comments

As a part of this work, we need to change the publish behavior to only deploy contents of the /dist folder.

Per our discussion today, node_modules should be at the Function App root, not in the dist folder.

I've been looking at what can be achieved with the code as it currently is and local running/debugging with Typescript and a folder structure similar to above can certainly be done (although there are manual set up steps). As you say, retooling is required to preserve CLI deployment.
See here if you're interested https://github.com/shladdergoo/insult-function/wiki/Debugging-Typescript-Azure-Functions-with-VS-Code

This is irrelevant/complete

@mbaroody - how did you create your functions? we changed our approach to using the scriptFile property on function.json, which should reference the correct .js output in "dist" (this section has more information). and what are the errors that you're running into?

@mhoeger sorry for the lack of details. here are the relavant files/outputs

here is my folder structure

dist/
node_modules/
src/
  Common/
  HttpTrigger/
    function.json
    index.test.ts
    index.ts
host.json
jest.config.js
local.settings.json
package-lock.json
package.json
tsconfig.json
tslint.json

contents of host.json

{
  "version":  "2.0",
  "extensions": {
    "http": {
      "routePrefix": ""
    }
  }
}

contents of src/HttpTrigger/function.json

{
  "disabled": false,
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "route": "some/route",
      "methods": [ "get" ]
    },
    {
      "authLevel": null,
      "type": "http",
      "direction": "out",
      "name": "res",
      "methods": null
    }
  ],
  "scriptFile": "../../dist/HttpTrigger/index.js"
}

turns out that the src/HttpTrigger/function.json file was not getting copied over to the dist folder. Resolved by changing the build stript in package.json to:

"build": "tsc && for func in `ls src/`; do cp \"src/${func}/function.json\" \"dist/${func}/function.json\"; done;"

but func azure functionapp publish <app-name> still doesn't work because the src/*/function.json files are not at the root level, so I got around it by adding the following publish script to package.json

"publish": "npm run build:production && for func in `ls src/`; do mkdir \"./${func}\"; cp \"./src/${func}/function.json\" \"./${func}/function.json\"; done && yes no | func azure functionapp publish IoTStagePlay-InventoryAPI --publish-local-settings && for func in `ls src/`; do rm -rf \"./${func}\"; done && npm install",

this is a hacky solution, have any other suggestions?

The main constraint that it looks like you ran into is that "function.json" files have to be in their own individual files one level above the root. Instead of moving the function.json files, you could move. the "host.json" and "local.settings.json" files into src. func commands can then be run with the --prefix dist argument to run from the new root of the function app (here is an example: https://github.com/mhoeger/typescript-template),

The TypeScript project template that we settled on (the template that automatically gets generated with VS Code or the func CLI) doesn't bother moving files, but uses the scriptFile property in function.json files to point to 'dist' output instead (example here: https://github.com/mhoeger/typescript-azure-functions). We settled on this approach over the approach above for a few reasons... one is that it's harder to get into a messed up, half-baked state because build output only comes from tsc and is only contained in dist. No other file manipulation is required (this was especially true when using bindings and needing to have an extensions.csproj). Another reason is that a lot of our tooling makes assumptions about the root of the project being the root of the function app too. This issue was opened first when we were leaning towards the first approach (moving .json files from src => dist).

Hope this context is helpful and let me know if things aren't working!

@mhoeger this is the simplest i've settled on

{
  "name": "",
  "version": "",
  "config": {
    "buildDir": "dist",
    "srcDir": "src",
    "azurefunctions_name": "function-app-name"
  },
  "scripts": {
    "build": "tsc",
    "postbuild": "copyfiles -u 1 $npm_package_config_srcDir/**/*.json $npm_package_config_srcDir/*.json $npm_package_config_buildDir && copyfiles package.json $npm_package_config_buildDir",
    "publish": "npm run test && npm run build && npm install --prefix $npm_package_config_buildDir --production && yes no | func azure functionapp publish $npm_package_config_azurefunctions_name --publish-local-settings --prefix $npm_package_config_buildDir",
    "start": "npm run build && func start --script-root $npm_package_config_buildDir",
    "test": "jest",
    "coverage": "jest --coverage"
  }
}

thanks!

Was this page helpful?
0 / 5 - 0 ratings