前言
利用Webstorm開發(fā)Node.js應用,最煩惱的就是代碼自動補全問題了。由于javaScript的弱類型特性,Webstorm等IDE在智能代碼補全功能上心有余而力不足,由Java、C++等轉過來的程序員會很不適應。這里介紹Webstorm支持的代碼自動補全功能,能夠一定程度緩解問題。
首先,看Webstorm的官方文檔:
https://www.jetbrains.com/help/webstorm/2016.3/creating-jsdoc-comments.html
里面講了Webstorm支持大部分的Google Closure Compiler的注解,并且能夠根據這些注解進行智能代碼補全。
這是Google Closure Compiler支持的注解,基本上是jsdoc規(guī)范的子集
https://github.com/google/closure-compiler/wiki/Annotating-Javascript-for-the-Closure-Compile
這是Google Closure Compiler類型及類型表達式規(guī)范
https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System
這里列舉一個代表的代碼段幾個常用的:
1自定義對象結構
/* ******************************************* * Copyright (c) 2016-2017 * XXXXXXXX Co.,Ltd. All rights reserved. * PRoject : Task * File : UserDao.js * Created : 2017-02-08 * Author : liangjiang * *******************************************/const crypto = require('crypto');const mongodb = require('./mongodb/mongodb');const User = require('../entity/User');const RandomUtil = require('../util/RandomUtil');const CODE = require('../../const/code');const logger = require('pomelo-logger').getLogger('debug-level', __filename, process.pid);const Collection = require('mongodb').Collection;/** * Class to Operate user. */class UserDao { /** @typedef {{username:string, passWord:string}} UserData */ /** * Create a new account. * * @param {UserData} opt * @return {Promise<?User>} */ static createNewAccount(opt) { return new Promise(function (resolve, reject) { let user; /** @type {Collection} */ let tempCollection; mongodb.collection('users') .then((/** Collection */collection) => { tempCollection = collection; return collection.findOne({username: opt.username}); }) .then((doc) => { if (doc == null) { let userData = { username: opt.username || '', password: UserDao._saltAndHash(opt.password || '') }; user = new User(userData); return tempCollection.insertOne(user.toObject(), {safe: true}); } else { resolve(null); } }) .then((result) => { user.setId(result.insertedId); resolve(user); }) .catch((err) => { logger.error(err); reject(err); }); }); } /** * Auto login. * * @param {UserData} opt * @return {Promise<?User>} */ static autoLogin(opt) { return new Promise(function (resolve, reject) { mongodb.collection('users') .then((/** Collection */collection) => { return collection.findOne({username: opt.username}); }) .then((doc) => { if (doc == null) { resolve(null); } if (doc.password == opt.password) { resolve(new User(doc)); } resolve(null); }) .catch(function (err) { logger.error(err); reject(err); }); }); } /** * Manual login. * * @param {UserData} opt * @return {Promise<User|number>} */ static manualLogin(opt) { return new Promise(function (resolve, reject) { mongodb.collection('users') .then((/** Collection */collection) => { return collection.findOne({username: opt.username}); }) .then((doc) => { if (doc == null) { resolve(CODE.AUTH.LOGIN.FA_USER_NOT_EXIST); } if (UserDao._validatePassword(opt.password, doc.password)) { resolve(new User(doc)); } else { resolve(CODE.AUTH.LOGIN.FA_PASSWORD_INVALID); } }) .catch((err) => { logger.error(err); reject(err); }); }); }; /** * Validate password. * * @private * @param {string} plainPass - Plain password. * @param {string} hashedPass - Hashed password. * @return {boolean} If equal. */ static _validatePassword(plainPass, hashedPass) { let salt = hashedPass.substr(0, 10); let validHash = salt + UserDao._md5(plainPass + salt); return hashedPass === validHash; } /** * Salt and hash. * * @private * @param {string} pass - Password to hash. * @return {string} Hashed password. */ static _saltAndHash(pass) { let salt = UserDao._generateSalt(); return salt + UserDao._md5(pass + salt); }; /** * Generate a salt. * * @private * @return {string} Random string of 10 characters. */ static _generateSalt() { return RandomUtil.randomString(10); }; /** * Calculate md5 value of a string. * * @private * @param {string} str - String to md5. * @return {string} Md5 value. */ static _md5(str) { return crypto.createHash('md5').update(str).digest('hex'); };}module.exports = UserDao;利用@typedef注解可以定義對象結構,如下:
/** @typedef {{username:string, password:string}} UserData */函數開頭的@private告訴Webstorm該方法是私有,Webstorm不會再外部調用時進行提示。
@param和@return可以定義函數的參數類型和返回值類型。
/** * Validate password. * * @private * @param {string} plainPass - Plain password. * @param {string} hashedPass - Hashed password. * @return {boolean} If equal. */如果是Promise類型,最好加上模板類型,既resolve(result)的中result的類型,這樣使用await時就不會提示有問題。/** * Deal with the command: downloadList. * * @param {object} req * @return {Promise<Answer>} */async function doDownloadList(req) { let /** Array<Download> */ downloads = await DownloadDao.getDownloads({targetId: req.session.target._id, status: 'unfinished'}); let data = []; for (let download of downloads) { data.push({id: download._id, saveName: download.filename}); } return {answer: 'ok', data: data};}更詳細的用法還是看上面那兩個關于Google Closure Compiler的鏈接吧,都是照那上面學的。
新聞熱點
疑難解答