As a strict Typescript developer you often want to keep your source files clean. However you do not want to bother with the bundled files.
This topic will teach you how to use gulp with FiveM to compile .ts files to the resources
directory.
Requirements:
- NodeJs v9+
- Basic Typescript and Javascript knowledge
Let’s start:
Place yourself on the resources folder level.
Create a src directory where your source files will live: mkdir src
.
Create a fresh resource folder: mkdir src/[essential]/ilog
.
Create a client and a server sub directory: mkdir src/[essential]/ilog/client src/[essential]/ilog/server
.
Create a __resource.lua file with this content:
server_scripts {
"server/server_main.js"
}
client_scripts {
"client/client_main.js"
}
The tree should looks like this:
Code your resource
Develop your resource under client and/or server as you usually did in Lua/Js.
You can create as many sub-folder ans .ts as you want.
How to build the whole thing?
If you didn’t initiate a npm package, please do npm init
on the top level, so the package.json will live beside src and resources.
Now on the same place, create a gulpfile.js file: touch gulpfile.js
Note: gulp is a toolkit for automating painful or time-consuming tasks in your development
.
Type the following: npm i --save-dev gulp gulp-typescript merge-stream gulp-concat
, it will install out dependencies.
Let’s import the dependencies in the gulpfile.js:
const gulp = require("gulp");
const ts = require("gulp-typescript");
const fs = require("fs");
const path = require("path");
const merge = require("merge-stream");
const concat = require("gulp-concat");
Now, we’ll create our “resource list”, for instance we just have one:
let folders = ["[essential]/ilog", "mySuperResource2"];
Note that we use the path taken from src.
Our build task:
gulp.task("build", function() {
let tasks = [];
// For each resource path in folder:
folders.map(el => {
// If there's a server folder
if (fs.existsSync(path.join("src", el, "server"))) {
tasks.push(
gulp
.src(`src/${escapeBracketPath(el)}/server/**/*.ts`)
.pipe(
ts({
noImplicitAny: true,
module: "commonjs"
})
)
.pipe(concat("main_server.js"))
.pipe(gulp.dest(`resources/${el}/server/`))
);
}
// If there's a client folder
if (fs.existsSync(path.join("src", el, "client"))) {
tasks.push(
gulp
.src(`src/${escapeBracketPath(el)}/client/**/*.ts`)
.pipe(
ts({
noImplicitAny: true,
module: "system",
outFile: "client_main.js"
})
)
.pipe(concat("main_client.js"))
.pipe(gulp.dest(`resources/${el}/client/`))
);
}
// Copy the __resource.lua
tasks.push(
gulp
.src(`src/${escapeBracketPath(el)}/__resource.lua`)
.pipe(gulp.dest(`resources/`))
);
});
// Merge all steams together
return merge(tasks);
});
Note: since gulp.src()
use node-glob
, we do need to escape our [ ] in the path, here is one solution I made:
// [essential]/ilog -> [[]essential]/ilog
// [essential]/[essential]/ilog -> [[]essential]/[[]essential]/ilog
const escapeBracketPath = path =>
path
.split("[")
.map((val, i) => (i != 0 ? `[]${val}` : val))
.join("[");
Execute it
- You can install
gulp
globally and directly usegulp build
- You can edit
package.json
:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "gulp build"
}
and now you’re able to launch the build task with this: npm run build
.
If the build succeed (no Ts compile error) you should now see your resource under resources:
I hope this will help you to be a STRONG Typescript developer.