Hey guys, it's been a while since I wrote a tutorial but this one is something I'm actually working on, so I decided to share with you what I learned ❤️.
BTW we are building a small wrapper for Pokeapi
what we will do
- Start a node project
- Install our dependencies
- Setup eslint & prettier
- Setup our package.json
- Start coding
- Setup small project for testing
- Let's Publish
Start a node project
So I will assume you at least know how to do this, but if not you have a picture down here:
You just need an empty folder and run the next command on it
npm init -y
Now I did some changes to my package.json (keywords, author, repo and version) you don't need to make this changes, but take a look at them if you will like to.
{
"name": "pokeapi",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
},
"keywords": [
"pokemon",
"api",
"sdk",
"typescript",
"tutorial"
],
"author": "David M.",
"license": "GPLv3"
}
You will notice scripts is empty 👀 we will fill it later
Install our dependencies
Now we will install one of our dev dependencies
npm install -D typescript
great! now we need another file on our folder root, it's called "tsconfig.json" you can copy the one that I used (below here) or you can generate it with the next command.
./node_modules/.bin/tsc --init
If you decided for this approach just make sure to adjust the declaration and outDir options according to the JSON bellow.
Setting the declaration attribute to true ensures that the compiler generates the respective TypeScript definitions files aside of compiling the TypeScript files to JavaScript files. The outDir parameter defines the output directory as the dist folder.
or just use mine ¯\_(ツ)_/¯
{
"compilerOptions": {
"target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"strict": true, /* Enable all strict type-checking options. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
"declaration": true,
"outDir": "./dist",
}
}
once we have this setup we will need to add some dependencies (this ones may not apply for your sdk)
npm install -S axios
now we are over with our dependencies... for now 👀
Setup eslint and prettier
Eslint
I think this part it's actually the shortest so let's start
you will need to run the next command:
npx eslint --init
Now... I recommend the next answers for the eslint init
Prettier
You need to run the next command
npm install -D prettier eslint-config-prettier eslint-plugin-prettier
After you have all that installed change the content of your .eslintrc.json
with this
{
"env": {
"es6": true,
"node": true
},
"extends": [
"airbnb-base",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 11,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {}
}
and add the file .prettierrc.json
with this inside
{
"printWidth": 100,
"tabWidth": 2,
"singleQuote": true,
"jsxBracketSameLine": true,
"trailingComma": "es5"
}
Setup our package.json
now that we finally have all the development setup ready we need to modify a bit our package.json
so it know it's a TypeScript project
{
"name": "pokeapi",
"version": "0.1.0",
"description": "",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prepare": "npm run build",
"build": "tsc"
},
"keywords": [
"pokemon",
"api",
"sdk",
"typescript",
"tutorial"
],
"author": "David M.",
"license": "GPLv3",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^3.9.0",
"@typescript-eslint/parser": "^3.9.0",
"eslint": "^7.6.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^3.1.4",
"prettier": "^2.0.5",
"typescript": "^3.9.7"
},
"dependencies": {
"axios": "^0.19.2"
}
}
If you notice, all that we changed is the scripts and added some settings main and types,
remember if you change your outputdir on tsconfig.json
change it on your package.json
.
Start coding
FINALLY
Let's make a new file called index.ts (on our root)
this is where our SDK will leave, we obviously and separate it on different files and import them but my example is short and simple so I will use the same file for all of it.
First we will import everything
import axios from 'axios';
Let's add some variables we will need
import axios from 'axios';
const API_URL: string = 'https://pokeapi.co/api/v2';
perfect! now that we have "all" setup lets start by adding our first sdk method (getPokemonById)
import axios from 'axios';
const API_URL: string = 'https://pokeapi.co/api/v2';
export function getPokemonById(id: number): Promise<object> {
return new Promise((resolve, reject) => {
axios
.get(`${API_URL}/pokemon/${id}`)
.then((resp) => {
resolve(resp.data);
})
.catch(reject);
});
}
export default { getPokemonById };
Finally our code should look something like this, notice that we export our function and as an export default we use "all of our functions" I will add another function so we can have a better idea of multiple functions working from the sdk. It should look like this...
import axios from 'axios';
const API_URL: string = 'https://pokeapi.co/api/v2';
export function getPokemonById(id: number): Promise<object> {
return new Promise((resolve, reject) => {
axios
.get(`${API_URL}/pokemon/${id}`)
.then((resp) => {
resolve(resp.data);
})
.catch(reject);
});
}
export function getPokemonTypeById(id: number): Promise<object> {
return new Promise((resolve, reject) => {
axios
.get(`${API_URL}/type/${id}`)
.then((resp) => {
resolve(resp.data);
})
.catch(reject);
});
}
export default { getPokemonById, getPokemonTypeById };
Setup small project for testing
Now that we have a really bare bones version of our SDK we will try to use it, but first we should build it!
for simplicity we will make a new node project inside our project like so...
npm run build
mkdir testing
cd testing
npm init -y
npm install ..
now this should make our new project ready to make import our sdk and running it.
my test looked a little like this
const pokeapi = require('pokeapi');
pokeapi.getPokemonById(1).then((pokemon) => {
console.log(pokemon.name);
});
// it should say "bulbasaur"
Let's Publish
Great to know that you made it until here ❤️
lets start right away!
we will need a new file called .npmignore
where we will add all the folders we don't want our sdk to bring with itself like our "testing" folder
it should look like this
testing/
and that should be all for your code ❤️
now the last part is to have an account on Npm do the next commands
npm login #do all the steps necessary
npm publish
and your sdk should be ready to be installed in any other node projects.
Here's some links that you might want:
Npm
Repo
I hope this quick tutorial really helped someone, because I wasn't lucky enough to find one as explicit as this one haha.
Top comments (7)
Good article. Thanks!
The following line can be removed as it is now merged github.com/prettier/eslint-config-....
Great article, thanks for share. the article does not cover the build of a single file sdk, here are some inputs.
a webpack.config.js file
install ts-loader, webpack-cli and npm script for build
build: "webpack"
this work for me and let me build a sdk in a single file.
in the html file dont forget to use
for include the js file and for the code
getting error:
ReferenceError: FormData is not defined
when added build to testing app
created a package.json file in the dist folder
repo: github.com/labeebshareef/typescrip...
This is awesome! I'm going to use this with a different API to learn how to build my own. I'm hoping to write my own resources afterward, because you're right, there is a lack of them!
Great article, thank you!
Can we use this sdk for plain javascript project?
Like writing sdk in typescript has support for plain js projects or not?
Nice article, it would be greate to cover configuration for baseUrl (to use it in your local/dev/staging env)