Search code examples
javascriptnode.jstypescriptbrowserify

How to use tsify with watchify on Ubuntu?


The input directory contains:

  1. a JavaScript file (a jQuery plugin that is not in the DefinitelyTyped repo) and
  2. 2 TypeScript files
    • declarations.d.ts
    • main.ts

The tsconfig.json file is this (work in progress):

{
    "compilerOptions": {
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": true,
        "outDir": "wp-content/themes/custom-theme/assets/js",
        "watch": true,
        "allowJs": true,
        "lib": ["ES2016", "DOM"]
    },
    "include": [
        "wp-content/themes/custom-theme/assets/ts"
    ],
    "exclude": [
        "node_modules",
        "**/*.spec.ts"
    ]
}

Currently I have this watch.sh script that works well:

tmux \
    new-session  'cd html && tsc' \; \
    split-window 'cd html/wp-content/themes && scss --watch custom-theme/assets/scss:custom-theme/assets/css' \; \
    split-window 'cd html/wp-content/themes && watchify custom-theme/assets/js/main.js -o custom-theme/assets/js/bundle.js'

I want to replace this script with something like a Browserify build.js file (I prefer build.ts if possible), and I want to use Tsify with Watchify (I understood that Watchify build.js file is similar to the Browserify file).

I have seen this example, but I am not sure if I am on the good road.

I have this not-working build.js file:

const browserify = require("browserify");
const tsify = require("tsify");

browserify()
    .plugin(tsify, { allowsJs: true })
    .add("wp-content/themes/custom-theme/assets/ts/main.ts")
    .bundle()
    .on('error', function (error) { console.error(error.toString()) })
    .pipe(process.stdout);

It does not even start to run: it says there is a syntax error on line 1 near (.

Any advice is greatly appreciated.

Thank you.

Update 1

The new build.js file:

const watchify = require("watchify");
const tsify = require("tsify");

watchify()
    .plugin(tsify, { allowsJs: true })
    .add("wp-content/themes/custom-theme/assets/ts/main.ts")
    .bundle()
    .on('error', function (error) { console.error(error.toString()) })
    .pipe(process.stdout);

runs but throws this:

$ node build.js 
/.../node_modules/watchify/index.js:14
    var cache = b._options.cache;
                  ^

TypeError: Cannot read property '_options' of undefined
    at watchify (/.../node_modules/watchify/index.js:14:19)
    at Object.<anonymous> (/.../build.js:4:1)
    at Module._compile (internal/modules/cjs/loader.js:1147:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
    at Module.load (internal/modules/cjs/loader.js:996:32)
    at Function.Module._load (internal/modules/cjs/loader.js:896:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47

Update 2

I ended up using this watch.sh shell script file:

tmux \
    new-session  'cd html && tsc' \; \
    split-window 'cd html/wp-content/themes; scss --watch custom-theme/assets/scss:custom-theme/assets/css' \; \
    split-window 'cd html/wp-content/themes; watchify custom-theme/assets/ts/main.ts -p [ tsify ] -o custom-theme/assets/js/bundle.js -v'

From here I understand that it respects the tsconfig.json file. The only issue is that the require call in main.ts does not return something that VS Code understands well, so I do not have autocompletition support. This is where I still need help. In future I would also like to use a build.js script, if there is anyone who can help me with this.


Solution

  • Now I use ES6 syntax for importing modules everywhere I import something. I also use relative paths to files inside the relevant npm packages in node_modules directory when I import from npm packages.

    In tsconfig.json I have these lines besides others:

    "target": "ES3",
    "lib": ["ES2020", "DOM"],
    "module": "CommonJS"
    

    The final working test project is here.

    I still have problems with some modules that are not prepaired for ES6 import.