Ede's Blog

那些没什么卵用的前端技巧

作为面向装逼编程的坚定的追随者,掌握几门工具,快速实现一些看起来高大上的功能,是不可或缺的优良品质。现我仅将一两门学(tou)来的手艺公布于此,以此感(hu)化(you)新教徒:

  1. 怎么搭建博客(hexo + github pages篇)

  2. 怎么构建命令行工具(npm篇)

  3. 怎么写Node插件( c++篇)

  4. 怎么构建桌面应用(Electron篇)

前言

本文属于抛砖引玉型文章,每一点均可深入探索,在此不展开;

本文的命令均基于Mac进行,Win下有差异,自行搜索解决;

假如遇到问题,给一些思路:

  • 保证网络顺畅可翻墙(或采用淘宝镜像)
  • Win下构建C++,npm install windows-build-tools(耗时几分钟到几个小时不等)
  • 遇到权限问题,sudo + 命令 或sudo chown -R ${whoami} ~/(掀桌子行为)
  • 请确保语法、路径、项目名正确

怎么搭建博客

HEXO:快速、简洁且高效的博客框架

  • 执行命令
npm install hexo-cli -g
hexo init blog
cd blog
npm install
hexo server
  • github创建Repo
  • 采用hexo-deployer-git
npm install hexo-deployer-git --save
  • 修改_config.yml
deploy:
type: git
repo: [email protected]:wps-word-fe/blog.git # git repo地址
branch: gh-pages
  • 构建:hexo d
  • github会默认启用github pages:eg:https://wps-word-fe.github.io/blog/
  • 假如没有绑定到更域名,需要更改root路径:/blog/(特指repo的名称)

怎么构建命令行工具

  • 创建项目
mkdir cmd && cd cmd && npm init
mkdir bin && cd bin && touch ./resume.js
npm install commander --save
#!/usr/bin/env node

// resume.js

const program = require('commander');

program.version('0.0.1').description('这是我的简历')
.option('-n, --nick', '我的名字')
.option('-a, --age', '我的年龄')
.option('-t, --total', '总览');

program.parse(process.argv);

if (program.nick) { console.log('乐乐');}
if (program.age) { console.log('25'); }

if (program.total) { console.log(
`
姓名:李健乐
学校:山东大学 专业:软件工程
职业:前端工程师 工作经验:三年
特长:
进能 搞不掂 我他妈今晚就不睡了
退能 保进度 一板砖拍死测试再说
`
)
}
  • 测试
node ./bin/cmd.js --help
node ./bin/cmd.js -n # 乐乐
node ./bin/cmd.js -a # 25
  • 发布
{
"name": "@edeity/resume",
"version": "0.0.1",
"description": "my resume cmd",
"main": "index.js",
"bin": {
"resume": "bin/resume.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"commander": "^2.20.0"
}
}
# npm config set registry "https://registry.npmjs.org"
npm login
npm publish --access public
# npm unpublish --force
# npm config set registry "https://registry.npm.taobao.org"
  • 测试
sudo npm install @edeity/resume --global
resume --help

怎么写Node插件

  • 创建项目
mkdir addons && cd addons && npm init
  • binding.gyp
{
'targets': [
{
'target_name': 'addons',
'sources': [],
"include_dirs" : [
"<!(node -e \"require('nan')\")"
],
'conditions': [
['OS == "mac"', {
'sources': [
'clipboard/cpb_mac.mm',
],
'libraries': [
'-framework AppKit',
]
}],
],
},
],
}

  • 编写C++代码
#include <nan.h>
#include <AppKit/AppKit.h>

void Method(const Nan::FunctionCallbackInfo<v8::Value>& info) {
v8::Local<v8::Array> fileArray = Nan::New<v8::Array>();

NSPasteboard *pboard = [NSPasteboard generalPasteboard];

// TODO Objective-C++ 自动引用回收问题
// TODO NSPasteboardTypeFileURL 只支持 10.13 以及以后的版本
NSString *fileURL = [pboard stringForType:NSPasteboardTypeFileURL];
NSString *fileName = [pboard stringForType:NSPasteboardTypeString];

if (fileURL != nil) {
const char *fileUtf8Name = [fileName UTF8String];
v8::Local<v8::String> tempName = Nan::New<v8::String>(fileUtf8Name).ToLocalChecked();
Nan::Set(fileArray, 0, tempName);
}
info.GetReturnValue().Set(fileArray);
}


void Init(v8::Local<v8::Object> exports) {
exports->Set(Nan::New("getClipboardFiles").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(Method)->GetFunction());
}

NODE_MODULE(clipboard, Init)
npm install node-gyp -g
npm install bindings nan --save
node-gyp configure
node-gyp build
  • 测试
var clipboard = require('bindings')('addons');
const process = require('process');

if(process.platform === 'darwin') {
console.log(clipboard.getClipboardData());
}

exports = module.exports = clipboard;
node index.js # your copy data

怎么构建桌面应用

  • CRA构建一个应用
npx create-react-app electron-app && cd electron-app && npm start
  • 声明electron入口main.js
// package.json
{
// ...
"main": "./public/electron.js",
"homepage": "./",
}
// main.js
const { app, BrowserWindow, Menu } = require('electron')
const path = require('path')
const url = require('url')
const IS_DEV = process.env.NODE_ENV === 'development'

let mainWindow

function createWindow() {
const menu = Menu.buildFromTemplate([])
Menu.setApplicationMenu(menu) // 设置菜单部分

// Create the browser window.
mainWindow = new BrowserWindow({
width: 600,
height: 400,
title: '大哥大嫂过年好!',
resizable: false,
transparent: true,
frame: false,
titleBarStyle: 'customButtonsOnHover',
// titleBarStyle: 'hidden',
hasShadow: false,
alwaysOnTop: true,
})

// 加载应用
const staticIndexPath = path.join(__dirname, './build/index.html');
const main = IS_DEV ? `http://localhost:3000` : url.format({
pathname: staticIndexPath,
protocol: 'file:',
slashes: true
})
mainWindow.loadURL(main)

mainWindow.on('closed', function () {
mainWindow = null
})
}

app.on('ready', createWindow)

app.on('window-all-closed', function () {
app.quit()
})

app.on('activate', function () {
if (mainWindow === null) {
createWindow()
}
})
  • 测试:
npm install electorn -g
NODE_ENV=development electron .
  • 构建
npm install electron-builder -g
rm -rf ./build && rm -rf ./dist
npm run build
electron-builder