前端構(gòu)造桌面級應(yīng)用(QQ音樂)

前端構(gòu)造桌面級音樂播放器(nw與electron)

服務(wù)端地址 http://majunchang.cn:3000/#/recommend

最近研究前端如何構(gòu)造桌面級應(yīng)用削茁,看了一下nw和ecectron。于是自己使用vue寫了一個pc版本的qq音樂播放器。由于時間太緊览徒,做的功能很有限挪捕。代碼重復(fù)率很高萨醒。希望可以體諒迁沫。本片文章主要是介紹nw與electron這兩個工具。前端的代碼已經(jīng)開源鸳粉,感興趣的同學(xué)可以自己下載下來扔涧,添加一些比較有趣的功能以及進(jìn)行代碼的優(yōu)化

附-使用 promise 實現(xiàn)前端緩存 ( recommend.vue 中給出示例代碼)

接口

//  分類歌單數(shù)據(jù)

export function getDiscList() {
  let href = window.location.href
  let url
  if (href.includes('localhost') || href.includes('127.0.0.1')) {
    url = '/api/getDiscList'
  } else {
    url = 'http://127.0.0.1:3000/api/getDiscList'
  }

  // 需要拼接的數(shù)據(jù)
  const data = Object.assign({}, commonParams, {
    platform: 'yqq',
    hostUin: 0,
    sin: 0,
    ein: 29,
    sortId: 5,
    needNewCode: 0,
    categoryId: 10000000,
    rnd: Math.random(),
    format: 'json'
  })

  return axios.get(url, {
    params: data
  })
}

緩存

import {
  getDiscList
} from './recommend.js'

let getDiscListCache
let test

function fn() {
  if (!getDiscListCache) {
    test = '測試變量'
    getDiscListCache = getDiscList() //  在此賦值  import 引入的時候 就向后端發(fā)送接口
  }
}
fn()

export {
  getDiscListCache,
  test
}

使用

methods: {
    getcateList() {
      getDiscListCache.then(res => {
        console.log(test);
        console.log(res);
        this.songList = res.data.data.list;
      });
    }
  }

項目預(yù)覽圖

分為首頁、歌手列表頁赁严、歌手詳情頁、排行榜粉铐。排行榜詳情頁以及播放器頁面疼约,排行榜與歌手頁基本一致 不做贅述

首頁
image
歌手列表頁
image
歌手詳情頁
image
歌手搜索功能
image
播放器頁面
image

技術(shù)棧

  • 前端 vue、vue-router蝙泼、webpack

  • 后端(代理) node+express做代理

  • 接口轉(zhuǎn)發(fā) jsonp axios

  • 打包工具 electron electron-packager

項目簡介

1. 數(shù)據(jù)獲取部分

  數(shù)據(jù)主要是獲取QQ音樂的接口程剥,有得接口jsonp的方式 就可以獲取到數(shù)據(jù) 有得接口需要使用Node做一下代理 來解決跨域

2. 代理轉(zhuǎn)發(fā)

在開發(fā)階段,我們可以使用vue中的dev模塊中的proxyTable進(jìn)行路徑的重寫和代理的轉(zhuǎn)發(fā)
在build的時候 我們可以手動配置 訪問路徑  或者使用express做一下配置 類似于我們將代碼 放入nginx服務(wù)器中那樣

3. 項目注意事項

我們需要在node啟動的服務(wù)器里面(也就是本地服務(wù)器中)解決跨域問題
使用nw的時候需要解決不能播放音頻的問題
index.html以及靜態(tài)資源的這些路徑問題

4. 項目優(yōu)化點

項目的css部分可以優(yōu)化 優(yōu)化為less汤踏,sass 或者cssmodule這樣
項目的組件可以抽離一下 目前排行榜詳情頁以及歌手詳情頁基本上的邏輯是一樣的 可以進(jìn)行抽使用組件化 也可以使用 slot
項目中 還可以新增很多功能 比如說播放mv  下載歌曲 以及添加我喜歡的音樂等

NodeJs+Express的代理

A 使用express 去訪問打包完成之后的dist目錄的靜態(tài)資源

B 為了解決 當(dāng)dist文件拖入nw打開 或者 直接打開dist目錄的index.html 以及使用electron打包之后 的接口訪問跨域問題

import path from 'path'
import express from 'express'
import axios from 'axios'
import {join} from 'path'

const app = express()

//  掛載靜態(tài)路徑
//  A
app.use(express.static(join(__dirname, '../../dist')))

let router = express.Router()

//  B
router.all('*', function (req, res, next) {
  // res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With')
  res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
  res.header('X-Powered-By', ' 3.2.1')
  next()
})

//  做代理的分發(fā)和請求  分類歌單
router.get('/getDiscList', function (req, res) {
  var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
  axios.get(url, {
    headers: {
      referer: 'https://c.y.qq.com/',
      host: 'c.y.qq.com'
    },
    params: req.query
  }).then((response) => {
    console.log('接口響應(yīng)成功')
    res.json(response.data)
  }).catch((e) => {
    console.log(e)
  })
})

router.get('/lyric', function (req, res) {
  var url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg'

  axios.get(url, {
    headers: {
      referer: 'https://c.y.qq.com/',
      host: 'c.y.qq.com'
    },
    params: req.query
  }).then((response) => {
    //  由于response 是一個jsonp格式的 所以我們要對這個 進(jìn)行json轉(zhuǎn)化
    var result = response.data
    var regExe = /^\w+\(({[^()]+})\)$/
    var matchArr = result.match(regExe)
    if (matchArr) {
      res.json(JSON.parse(matchArr[1]))
    }
  }).catch((e) => {
    console.log(e)
  })
})

app.use('/api', router)

app.listen(3000, () => {
  console.log('服務(wù)器已經(jīng)啟動,監(jiān)聽的端口號是3000')
})

?

nw(node-weikit的簡介與使用)

node-webkit的簡介

官網(wǎng)需要翻墻 下載需要翻墻 (唉...... 在這里貼一下nw的官網(wǎng)首頁和下載截圖)

image
image

Github上nw.js有兩萬多Star和接近3000的Fork织鲸,說明它已經(jīng)相當(dāng)成熟。 并且在Github項目的最后面溪胶,顯示Intel有贊助這個項目搂擦,看起來很牛的樣子

  • nw.js也是一個使用前端技術(shù)(html、css哗脖、JavaScript)來構(gòu)建pc端程序的一個框架瀑踢。
  • 可以兼容windows xp系統(tǒng)
  • 支持用HTML5, CSS3, JS和WebGL來寫應(yīng)用程序,包括桌面端和移動端才避;
  • 完全支持Node.js APIs和所有的第三方模塊橱夭;
  • 性能也不會很差,對于輕量級的應(yīng)用足夠了桑逝;
  • 對應(yīng)用進(jìn)行打包和發(fā)布十分簡單棘劣,也就是說寫一份代碼很容易移植到不同的平臺(包括主流的Linux, Mac OS X 和 Windows);
nw能做什么楞遏?

nw.js就是使HTML, CSS, JavaScript寫的原本在瀏覽器上運行的程序茬暇,也可以在桌面端運行。

image
nw的安裝與使用
  1. 下載安裝包安裝(建議大家下載帶有開發(fā)包的 便于調(diào)試)

    官網(wǎng)下載nw.app的壓縮包 解壓以后即可使用

附官網(wǎng)地址: https://github.com/nwjs/nw.js

效果圖:
image

image
  1. 使用命令行安裝 (命令行下載比較慢 所以不是特別建議)
sudo npm install -g nw
nw的打包流程

打包工具 (簡單介紹幾種 )

  • nodebob是node-webkit的構(gòu)建工具寡喝,可以在Windows環(huán)境中自動發(fā)布node-webkit應(yīng)用程序而钞。目前在v0.1中,用windows批處理腳本編寫拘荡。
  • nw-builder&grunt-nw-builder允許您使用grunt為mac臼节,win和linux構(gòu)建node-webkit應(yīng)用程序。他們將下載特定版本的預(yù)構(gòu)建二進(jìn)制文件,解壓縮它网缝,創(chuàng)建一個版本文件夾巨税,為指定目錄創(chuàng)建app.nw文件,并將app.nw文件復(fù)制到它所屬的位置
  • Nuwk粉臊!Nuwk草添!可以輕松地基于node-webkit創(chuàng)建Mac應(yīng)用程序,從而簡化測試和構(gòu)建過程扼仲。它負(fù)責(zé)創(chuàng)建可執(zhí)行文件远寸,附加應(yīng)用程序圖標(biāo)并相應(yīng)地配置plist文件。(非常alpha階段)
  • generator-node-webkit是一個yeoman生成器屠凶,用于開發(fā)node-webkit應(yīng)用程序并為mac驰后,linux和win創(chuàng)建包。
    松集成到您的構(gòu)建過程中矗愧,它將為Linux灶芝,Windows和OSX下載nwjs 32 / 64bit,并從給定的源目錄為所有3個平臺構(gòu)建軟件包唉韭。

windows下的打包流程
https://www.cnblogs.com/tinyphp/p/5052327.html

mac/osx下的打包流程

https://blog.csdn.net/weichuang_1/article/details/48849335

https://blog.csdn.net/baidu_30907803/article/details/78795405

nw解決不能播放音頻問題

MP3編碼屬于專利編碼夜涕,非開源授權(quán)的,所以在nw.js中默認(rèn)不支持MP3的播放属愤,需要手動啟用才行女器。

需要從社區(qū)中下載對應(yīng)版本的libffmpeg.dll文件 然后將原來的替換一下即可解決

社區(qū)地址: https://github.com/iteufel/nwjs-ffmpeg-prebuilt/releases

目標(biāo)文件地址: /Users/baidu/Desktop/nwjs-sdk-v0.31.1-osx-x64/nwjs.app/Contents/Versions/67.0.3396.79

我把這個軟件安裝在了桌面上 這是目標(biāo)地址 大家只要記住后面的就行,Versions后面的數(shù)字 代表的nw內(nèi)嵌的谷歌版本(不一樣也沒事)

nw的使用以及如何調(diào)試

通過快捷鍵 option+command+i 打開內(nèi)置谷歌的控制臺。如果不能打開 或沒反應(yīng) 有可能是大家下載的版本 不是帶開發(fā)工具的

nw的應(yīng)用

nwjs——你值得擁有住诸!
不得不提nw.js開發(fā)出的應(yīng)用已經(jīng)涵蓋了許多領(lǐng)域:

  1. WhatsApp 經(jīng)典的聊天應(yīng)用晓避,還有Messenger;
  2. Powder Player 種子下載只壳,以及視頻播放器俏拱;
  3. Boson Editor 代碼編輯器,甚至還有一款Markdown編輯器叫Story-writer吼句;
  4. Leanote Desktop App 類似Evernote的筆記類應(yīng)用程序;
  5. Mongo Management Studio 數(shù)據(jù)庫管理應(yīng)用惕艳。

electron(簡介與使用)

官網(wǎng)地址 (不用翻墻 這一點很棒)

https://electronjs.org/

image

簡介

  • electron 是一個可以讓我們使用js創(chuàng)建桌面應(yīng)用程序的框架搞隐,并且可以很簡單的實現(xiàn)跨平臺,讓我們可以更輕松的書寫業(yè)務(wù)邏輯远搪,而不用擔(dān)心跨平臺的問題劣纲。
  • 與nw相比,electron的使用人數(shù)更多谁鳍,文檔更加齊全癞季,使用起來也更加方便劫瞳。
  • 社區(qū)很強(qiáng)大,基本上你遇到的問題 都可以在社區(qū)中解決。

官方示例

# 克隆示例項目的倉庫
$ git clone https://github.com/electron/electron-quick-start

# 進(jìn)入這個倉庫
$ cd electron-quick-start

# 安裝依賴并運行
$ npm install && npm start

項目截圖

image
image

electron的安裝與打包工具的安裝

  • 全局安裝electron

    npm install electron -g
    
  • 本地安裝

    npm install electron --save-dev
    
  • 打包工具

    這里的打包工具我選擇的是electron-packager

    在項目中 安裝打包工具 然后配置一下命令行

    npm install --save-dev electron-packager
    

    ?

    {
      "name": "qq-music",
      "version": "1.0.0",
      "description": "A Vue.js project",
      "author": "junchang.ma.ele_waimai <junchang.ma@ele.me>",
      "private": true,
      "scripts": {
        "dev": "webpack-dev-server --host 0.0.0.0 --inline --progress --config build/webpack.dev.conf.js",
        "start": "npm run dev",
        "build": "node build/build.js",
        "electron_dev": "electron build/electron.js",
        "electron_build": "electron-packager ./dist/ --platform=darwin --arch=x64 --overwrite"
      },
      "dependencies": {
        ....
      },
      "devDependencies": {
        ...
      },
      "engines": {
        "node": ">= 6.0.0",
        "npm": ">= 3.0.0"
      },
      "browserslist": [
        "> 1%",
        "last 2 versions",
        "not ie <= 8"
      ]
    }
    
    

    說一下命令行配置:

    packager": "electron-packager ./app HelloWorld --all --out ./OutApp --version 1.4.0 --overwrite --icon=./app/img/icon/icon.ico"
    

    ?

    • location of project:項目所在路徑
    • name of project:打包的項目名字
    • platform:確定了你要構(gòu)建哪個平臺的應(yīng)用(Windows绷柒、Mac 還是 Linux) win32=> windows下 darwin=> mac
    • architecture:決定了使用 x86 還是 x64 還是兩個架構(gòu)都用
    • electron version:electron 的版本
    • optional options:可選選項

    字段里的 項目名字志于,version,icon路徑要改成自己的废睦;

electron的打包(將electron集成在vue中)

命令行配置 參考上面

本地預(yù)覽模式

  • 在build文件夾下 生成一個electron.js

    // Modules to control application life and create native browser window
    const {app, BrowserWindow} = require('electron')
    // import path from 'path'
    const path = require('path')
    // Keep a global reference of the window object, if you don't, the window will
    // be closed automatically when the JavaScript object is garbage collected.
    let mainWindow
    
    function createWindow () {
      // Create the browser window.
      mainWindow = new BrowserWindow({width: 800, height: 600})
    
      // and load the index.html of the app.
      mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
    
      // Open the DevTools.
      // mainWindow.webContents.openDevTools()
    
      // Emitted when the window is closed.
      mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null
      })
    }
    
    // This method will be called when Electron has finished
    // initialization and is ready to create browser windows.
    // Some APIs can only be used after this event occurs.
    app.on('ready', createWindow)
    
    // Quit when all windows are closed.
    app.on('window-all-closed', function () {
      // On OS X it is common for applications and their menu bar
      // to stay active until the user quits explicitly with Cmd + Q
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })
    
    app.on('activate', function () {
      // On OS X it's common to re-create a window in the app when the
      // dock icon is clicked and there are no other windows open.
      if (mainWindow === null) {
        createWindow()
      }
    })
    
    // In this file you can include the rest of your app's specific main process
    // code. You can also put them in separate files and require them here.
    
    

    ?

打包模式

  1. 將build目錄的下electron.js 復(fù)制到dist文件中一份

  2. 配置一個package.json

    {
      "name": "nw-qqMusic",  項目名稱
      "version": "0.0.1",     版本號
      "main": "electron.js"   項目入口文件
    }
    
    
  3. 在項目根目錄的命令行中 運行

    npm run build 
    npm run electron_build
    

Nw與Electron的對比

  1. nw.js無論從表面還是本質(zhì)都更接近 Node.js伺绽,nw.js直接繼承和使用了node.js的啟動、開發(fā)嗜湃、運行方式奈应,對node.js的修改最小,而 electron的改動很大购披,增加了很多自己的東西杖挣,使用起來感覺與node.js差別明顯。nw.js是和node.js一樣是單進(jìn)程的今瀑,electron改成了雙進(jìn)程程梦,技術(shù)實現(xiàn)改變点把。
  2. electron的優(yōu)點:開源的核心擴(kuò)展比較容易橘荠,界面定制性強(qiáng),原則上只要是Web能做的他都能做郎逃。是目前最廉價的跨平臺技術(shù)方案哥童,相對其他跨平臺方案(如 QT GTK+ 等),更穩(wěn)定褒翰,bug少贮懈, 畢竟只要瀏覽器外殼跑起來了,里面的問題不會太多 优训。
  3. electron的缺點:
    • 卡朵你,啟動慢,這可能是webkit的鍋揣非。畢竟一個瀏覽器要支持的功能確實有點多抡医。
    • 除了主進(jìn)程 你可能還需要啟動一些輔助進(jìn)程來完成工作。而每當(dāng)你新開一個進(jìn)程早敬,起步價就是一個nodejs的內(nèi)存開銷忌傻!
    • 丟幀,這個最嚴(yán)重搞监,可我已習(xí)慣了native 的絲滑. mac下感覺還可以 win下有點夠嗆水孩。
    • 打出來的包太大。(很顯然琐驴,即便是一個空包俘种,也至少包含了一個瀏覽器的體積
  4. NW.js對庫的整合更深秤标,某種意義上說,對chromium和Node有更深入的理解(新功能要用安疗,必須把源碼拿來build進(jìn)去)抛杨。
  5. 從license上來看,Electron是Github的荐类,NW.js則是Intel怖现。
  6. nw 在mac上只能構(gòu)建mac的應(yīng)用 ,windows下只能構(gòu)建windows的玉罐。而electron 可以通過命令行構(gòu)建不同環(huán)境下的 linux mac和windows等

資料文檔

qq音樂接口獲取方式的相關(guān)文檔

https://blog.csdn.net/xiayiye5/article/details/79487560
https://blog.csdn.net/hhzzcc_/article/details/79769386
https://segmentfault.com/a/1190000007685830

nw相關(guān)資料

electron的相關(guān)資料

打造你的第一個electron應(yīng)用

github地址

常用打包工具

Electron: 從零開始寫一個記事本app

electron打包:electron-packager及electron-builder兩種方式實現(xiàn)(for Windows)

electron-packager命令常用參數(shù)大全

探索與思考

實現(xiàn)讓div的高度也自適應(yīng)的方式 和寬度始終成一個比例屈嗤,能有幾種實現(xiàn)方法?

項目地址與啟動方式

克隆項目地址  
git clone https://github.com/majunchang/QQ-music.git
安裝依賴 
npm i  
cd  nodeServer
npm i
啟動Node代理 在nodeServer文件夾下
npm run dev 
本地預(yù)覽 (項目的根目錄下)
npm  run dev  

本地electron預(yù)覽
npm  run electron_dev

打包編譯

npm run build 
npm run electron_build

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吊输,一起剝皮案震驚了整個濱河市饶号,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌季蚂,老刑警劉巖茫船,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扭屁,居然都是意外死亡算谈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門料滥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來然眼,“玉大人,你說我怎么就攤上這事葵腹「呙浚” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵践宴,是天一觀的道長鲸匿。 經(jīng)常有香客問我,道長阻肩,這世上最難降的妖魔是什么带欢? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮磺浙,結(jié)果婚禮上洪囤,老公的妹妹穿的比我還像新娘。我一直安慰自己撕氧,他們只是感情好瘤缩,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伦泥,像睡著了一般剥啤。 火紅的嫁衣襯著肌膚如雪锦溪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天府怯,我揣著相機(jī)與錄音刻诊,去河邊找鬼。 笑死牺丙,一個胖子當(dāng)著我的面吹牛则涯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播冲簿,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粟判,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了峦剔?” 一聲冷哼從身側(cè)響起档礁,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吝沫,沒想到半個月后呻澜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡惨险,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年羹幸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片平道。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡睹欲,死狀恐怖供炼,靈堂內(nèi)的尸體忽然破棺而出一屋,到底是詐尸還是另有隱情,我是刑警寧澤袋哼,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布冀墨,位于F島的核電站,受9級特大地震影響涛贯,放射性物質(zhì)發(fā)生泄漏诽嘉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一弟翘、第九天 我趴在偏房一處隱蔽的房頂上張望虫腋。 院中可真熱鬧,春花似錦稀余、人聲如沸悦冀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盒蟆。三九已至踏烙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間历等,已是汗流浹背讨惩。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工对竣, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留量窘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓蛋欣,卻偏偏與公主長得像寡夹,于是被迫代替她去往敵國和親靴患。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容