QiaoranC 2019-06-25
所有的入门教程几乎都从“Hello World”讲起,这个也不例外。
接上文,我们的项目目前还是个空壳子,什么都没有,现在要先进行项目初始化操作。
View
-Integrated Terminal
来打开内置的Terminalnpm init
命令来创建package.json文件,许可证那我该成了MIT,其它基本都是默认,直接回车即可安装koa及对应的types,这里建议再安装一遍typescript,这样可以保持其版本跟着这个项目走,而不是全局
npm install koa --save npm install @types/koa --save-dev npm install typescript --save-dev
执行完上述命令后根目录下会新增package-lock.json文件,这个文件是只有npm v5.0以上版本才会生成的,其与yarn工具生成yarn.lock文件类似,主要是用来记录已安装模块的整个依赖关系,下次install时直接根据该文件去获取依赖库,具体情况可以看官方文档:https://docs.npmjs.com/files/...--save
选项指将其该依赖保存至package.json中的dependencies
下,如果后面有-dev
,则保存至devDependencies
下
安装好一些基础依赖库之后,我们需要配置一下tsconfig,这个配置文件用于typescript将/.tsx?/
文件编译成js,里面有很多配置项,具体可以查看这个中文文档:https://tslang.cn/docs/handbo...
在根目录
下面新建一个tsconfig.json
文件
// ./tsconfig.json { "compilerOptions": { "outDir": "./dist/", "target": "es5" } }
最简单的配置就是上面这样,设定好要编译后的js版本(target
),和编译后js要输出到的所在目录(outDir
)。
PS:为啥要用typescript,因为ts是es的超集,还有类型检查,另外不再需要babel,简单来说,babel有的ts都有,babel没有的ts也有
我们在服务端目录下新建index.ts作为服务端入口,另外新建一个config.ts作为服务端配置项文件。
// ./src/server/config.ts export default { port: 3344, };
// ./src/server/index.ts import * as Koa from 'koa'; import serverConfig from './config'; const app = new Koa(); const { port } = serverConfig; app.use((ctx: Koa.Context, next) => { ctx.body = 'hello world'; next(); }); app.listen(port, () => { console.log(`Koa app started at port ${port}`); });
疑问一:为何要import * as Koa from 'koa';而不是import Koa from 'koa';?
答:这个问题涉及到import语句的基本语法(见MDN import),很多同学在配合babel的时候都习惯于使用后者这种方式。前者导入所有内容,后者导入默认值。查看koa的源码可见其使用module.exports来设置要导出的内容,根据上述tsconfig中target为es5,此时ts会使用对于es5的默认模块规范即commonjs来处理这些导入导出的模块,而koa源码中并没有设置导出的默认值,即default值,所以需要使用前者这种写法,而babel会做额外的处理(见exporting 'exports.default' rather than 'exports'),使得可以使用后者这种写法。
疑问二:我就想在ts里使用import Koa from 'koa';这种写法,该怎么办?
答:在tsconfig.json中添加如下属性:
// ./tsconfig.json { ... "compilerOptions": { ... "allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。这并不影响代码的显示,仅为了类型检查。 ... } ... }
疑问三:为何不直接import { port } from './config';而要写两行代码?
答:import语句中的{ a }
,和es6中const { b } = xxx;
并不是同一回事,前者是导入模块的单个成员a,后者是解构xxx对象的属性b,而port根本不是config导出的模块成员之一,config只导出了一个模块成员即default。
疑问四:Koa.Context是什么东西?“ctx: Koa.Context”又是什么语法?
答:ts中对于变量可使用:
对其进行类型声明,这里的Koa.Context即ctx上下文的类型。
我们将鼠标移上去可以看到简要信息,点击可以跳转到详细的类型声明文件中看到具体的定义。
我们使用tsc命令来编译ts文件,为了方便调用,我将编译命令写入了package.json文件中的scripts属性下。
// ./package.json { ... "scripts": { ... "tsc": "tsc -w -p tsconfig.json", ... }, ... }
执行以下命令:
npm run tsc
可以看到控制台出现上述信息,且不能再进行输入命令了,另外我们在根目录下发现多出一个dist
目录,里面有两个文件,config.js和index.js。
疑问五:为什么生成的文件不是在./dist/server目录下,而是直接在./dist下了?
答:这个可以说(我猜测,可能有配置方法,但目前我没找到)是一个bug,主要表现就是被编译的ts文件都处于一个目录下,那么生成的js文件都会直接被导出到dist目录下,为了避免此问题,我们在./src/client目录下新建一个空的index.ts文件,重写执行编译命令即可生成正确目录下的文件了。
我们使用node来启动我们的koa app,同样我将该命令放在了package.json文件中。
// ./package.json { ... "scripts": { ... "dev": "node ./dist/server/index.js", ... }, ... }
执行以下命令:
npm run dev
打开浏览器,访问以下地址:
http://localhost:3344
可见hello world出现。
疑问六:怎么再开一个vs code里的terminal?
答:如下图,在原terminal窗口右上角按小加号即可
By devlee