serverless / serverless-plugin-typescript

Serverless plugin for zero-config Typescript support

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Symbolic Link fails on Windows

josenicomaia opened this issue · comments

There is a know problem on windows when the creation of symbolic links are need. The UAC filter the symbolic link permission and don't let the user use it. You must open the console as administrator to use this resource.

Steps to Reproduce:

  1. Have a windows machine;
  2. Open a console without admin rights;
  3. Install plugin;
  4. invoke local.

Error:

PS C:\Jose\Dropbox\Github\AutoKariam> serverless invoke local -f hello
Serverless: Compiling with Typescript...
Using local tsconfig.json

Error --------------------------------------------------

EPERM: operation not permitted, symlink 'C:\Jose\Dropbox\Github\AutoKariam\node_modules' -> 'C:\Jose\Dropbox\Github\AutoKariam.
build\node_modules'

 For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

Stack Trace --------------------------------------------

Error: EPERM: operation not permitted, symlink 'C:\Jose\Dropbox\Github\AutoKariam\node_modules' -> 'C:\Jose\Dropbox\Github\AutoKariam.build\node_modules'
at Object.fs.symlinkSync (fs.js:961:18)
at ServerlessPlugin. (C:\Jose\Dropbox\Github\AutoKariam\node_modules\serverless-plugin-typescript\dist\src\index.js:80:20)
at Generator.next ()
at fulfilled (C:\Jose\Dropbox\Github\AutoKariam\node_modules\serverless-plugin-typescript\dist\src\index.js:4:58)
at process._tickDomainCallback (internal/process/next_tick.js:129:7)
From previous event:
at PluginManager.invoke (C:\Users\José\AppData\Roaming\npm\node_modules\serverless\lib\classes\PluginManager.js:217:22)
at PluginManager.run (C:\Users\José\AppData\Roaming\npm\node_modules\serverless\lib\classes\PluginManager.js:236:17)
at variables.populateService.then (C:\Users\José\AppData\Roaming\npm\node_modules\serverless\lib\Serverless.js:107:33)
at runCallback (timers.js:649:20)
at tryOnImmediate (timers.js:622:5)
at processImmediate [as _immediateCallback] (timers.js:594:5)
From previous event:
at Serverless.run (C:\Users\José\AppData\Roaming\npm\node_modules\serverless\lib\Serverless.js:94:74)
at serverless.init.then (C:\Users\José\AppData\Roaming\npm\node_modules\serverless\bin\serverless:30:50)

Fonts:

https://github.com/jprichardson/node-fs-extra#windows
https://ember-cli.com/user-guide/#enabling-symlinks

Fonts for Solution:

https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy-sync.md
https://nodejs.org/api/fs.html#fs_fs_symlinksync_target_path_type
https://stackoverflow.com/questions/39106516/node-fs-copy-a-folder

You can use my fork like temporary solution for Winidows. In package. json:

    "serverless-plugin-typescript": "EugeneDraitsev/serverless-plugin-typescript#build"

@EugeneDraitsev solution worked like a charm, now I don't need to have a powershell administrative window opened.
Thanks a lot.

Will be nice if @schickling can take a look my pr and release this fix in next version of plugin

Any updates about a permanent solution to this issue?

I think everyone, who stacked with this problem should move from serverless-plugin-typescript
to serverless-webpack-plugin. So you need just add it (with typescript, ts-loader and webpack ) to devDependencies :

yarn add -D webpack typescript serverless-webpack ts-loader 

add plugin in serverless.yml:

...
plugins:
- serverless-webpack
...

add webpack.config.js file to root of your project:

const path = require('path');
const slsw = require('serverless-webpack');

module.exports = {
  entry: slsw.lib.entries,
  mode: 'development',
  target: 'node',
  resolve: {
    extensions: [
      '.js',
      '.json',
      '.ts',
      '.tsx',
      '.mjs',
    ],
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.ts(x?)$/,
        use: [
          {
            loader: 'ts-loader',
          },
        ],
      },
      {
        type: 'javascript/auto',
        test: /\.mjs$/,
        use: []
      },
    ],
  },
};

And it's done. I hope you solve your serverless-typescript problem with this simple and nice workaround.

Another option is to not use any plugin at all. In my last project I've done it that way and it worked like a charm (actually, the files watch through nodemon was faster).

nodemon.js executes this on every file change:
"exec": "rm -rf dist && tsc && sls offline --package package"

and tsconfig.json's outDir points to "dist".
The final package is generated in a "package" folder, but there's no reason to keep that.

@didac-wh this is interesting, could you elaborate with more detail?
Compiling typescript in a dist directory does not make serverless pick it up. What kind of configuration should we setup?

@colthreepv Your serverless.yml function handlers should specify the file in the dist/ folder. e.g:

user:
    handler: dist/src/module/User/UserRouter.handler
    events:
      - http: ANY /user
      - http: 'ANY /user/{proxy+}'

And this would be the nodemon.json file:

{
  "exec": "rm -rf dist && tsc && sls offline --package package",
  "ignore": [
    "node_modules",
    "dist/**/*",
    "package/**/*",
    ".git",
    "script/**/*"
  ],
  "ext": "ts json"
}

So nodemon only watches the files you are actually coding, not the compiled/transpiled ones, nor the third party modules, nor the ones generated by the serverless package.

Let me know if I can help further.

A fix for this has been released in version 1.1.7 🎉

Please re-open a new issue if you think this is still relevant 😄