使用到的技能點
- vue2
- webpack
- NW.js
- Node.js
一、前言
先講一下這個專案的由來。我司要新上一個產品,是面向教育領域的一個東西,要求快速開發又必須要相容 XP
,所以就選 NW.js 來做桌面客戶端。同時,前端的輪子方面,開始嘗試在面向使用者的業務上應用 vuejs 。
在這個過程中,也踩到了一些坑,也學到了一些新的小技巧,分享出來給大家參考一下。
有同學問,為啥不直接出一個完整專案?
我想等 webpack 升級完 webpack2 的時候再來一個懶人 seed 專案包吧
二、vue&webpack 專案搭建
首先用 vue-cli 快速的搭建一個 webpack 模板專案,省心又省事兒。
這部分不做過多介紹,很容易的。
方便新人理解和學習,給個參考連結 github.com/vuejs-templ…
三、NW.js 的建構
整個 nw 建構是基於 vue&webpack 這個前置步驟的專案的。
好了,我們開始。
1、先用 npm 安裝 NW.js
1) 能順利翻牆
NW.js 開發者們提供了 nwjs/npm-installer
如果您的網速較好,翻牆順利的話,可以直接
npm install nw --nwjs_build_type=sdk --save複製程式碼
2) 網路不太好
當然我的網路情況就不是很好,233333
這時候可以先下載好 nw 的 sdk 包到本地,牆外地址:dl.nwjs.io/v0.20.1/nwj… (截至目前現在最新的sdk版本是 0.20.1
,系統環境是 win10 x64)當然,我作為一個老司機,也有不可推卸的責任,我把我這個包也發到了百度雲上了:連結: pan.baidu.com/s/1i52ZO8l 密碼: 3tt2
做了點微小的貢獻,謝謝大家。
我已經嘗試過 file://
那個方法不能用了,換server模式吧
切換命令列目錄到當前sdk包所在位置
C:\Users\anchengjian\Downloads> mkdir 0.20.1
C:\Users\anchengjian\Downloads> cp nwjs-sdk-v0.20.1-win-x64.zip ./0.20.1複製程式碼
再開啟 server 服務,如果有python直接
C:\Users\anchengjian\Downloads> python -m SimpleHTTPServer 9999複製程式碼
或者換個姿勢
C:\Users\anchengjian\Downloads> npm install http-server -g
C:\Users\anchengjian\Downloads> http-server -p 9999複製程式碼
服務開好就可以繼續下一步了,切換目錄到專案程式碼的目錄下。
先建立一個 .npmrc
檔案,內容如下:
nwjs_build_type=sdk
NWJS_URLBASE=http://localhost:9999/複製程式碼
再然後直接 npm 安裝 nw
E:\code\vue-webpack-nw> npm i nw --save複製程式碼
這時,如無其他問題,已經裝好了。
2、這時候開始增補nw相關的建構
下文直接以檔名為小標題
1) package.json
{
"name": "vue-webpack-nw",
"version": "1.0.0",
"description": "vue-webpack-nw",
"author": "anchengjian <anchengjian@gmail.com>",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src"
},
"dependencies": {
// ...
},
"devDependencies": {
// ...
},
"engines": {
"node": ">= 7.0.0",
"npm": ">= 4.0.0"
},
// 以下為 nw 的配置新加內容
"main": "./index.html",
"window": {
"title": "nw-vue-webpack2",
"toolbar": true,
"frame": true,
"width": 1200,
"height": 800,
"min_width": 800,
"min_height": 500
},
"webkit": {
"plugin": true
},
"node-remote": "http://localhost:8080"
}複製程式碼
2) build/webpack.base.conf.js
增加基礎配置
module.exports = {
// ...
// 以下為新加內容
target: 'node-webkit'
}複製程式碼
3) build/dev-nw.js
新建一個名為 dev-nw.js
的檔案
內容如下,直接copy吧。
原理我就不講了,大致實現的功能是:
先用 Node.js
修改當前專案 index.html
內容為打包出來的 index.html
,然後再用 nw 開啟當前專案目錄,當關閉或者報錯的時候再還原 index.html
,當前,你直接 kill 程式,這個還原就會出問題。自己看著改吧,233333
const path = require('path')
const url = require('url')
const fs = require('fs')
const http = require('http')
const exec = require('child_process').exec
const rootPath = path.resolve(__dirname, '../')
const nwPath = require('nw').findpath()
// 修改index.html檔案中的css和js的地址
const indexHtmlPath = path.resolve(__dirname, '../index.html')
const indexHtmlContent = fs.readFileSync(indexHtmlPath, 'utf-8').toString()
// 退出時恢復原樣子
process.on('exit', exitHandle)
process.on('uncaughtException', exitHandle)
function exitHandle(e) {
fs.writeFileSync(indexHtmlPath, indexHtmlContent, 'utf-8')
console.log('233333,bye~~~')
}
// get uri
var config = require('../config')
if (!process.env.NODE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
var port = process.env.PORT || config.dev.port
var uri = `http://localhost:${port}/`
// start lauch NW.js
requestGet(uri, htmlText => {
htmlText = htmlText.replace('src="/', `src="${uri}`).replace('href="/', `href="${uri}`)
fs.writeFileSync(indexHtmlPath, htmlText, 'utf-8')
let runNwDev = exec(`${nwPath} ./`, { cwd: rootPath }, (err, stdout, stderr) => {
if (err) process.exit(0)
})
runNwDev.stdout.on('data', (data) => console.log(data))
})
function requestGet(path, callback) {
console.log('start with request: ', path)
const options = Object.assign({ method: 'GET' }, url.parse(path))
const req = http.request(options, res => {
let body = []
res.on('data', chunk => body.push(chunk))
res.on('end', () => callback(Buffer.concat(body).toString()))
})
req.on('error', e => console.log('problem with request: ' + e.message))
req.write('')
req.end()
}複製程式碼
4) build/dev-server.js
在其最末尾修改一下,不需要開啟瀏覽器,而是需要其程式碼驅動開啟nw.exe
// when env is testing, don't need open it
if (process.env.NODE_ENV !== 'testing') {
// opn(uri)
// modify by anchengjian
// 這兒不需要開啟瀏覽器,只用開啟 nw 就行
require('./dev-nw')
}複製程式碼
5) build/dev-client.js
這個時候直接在執行 npm run dev
正常的話是可以用 nw.exe 開啟當前專案程式碼,但接著就可以看到有一個報錯
GET chrome-extension://hbdgiajgpfdfalonjhdcdmbcmillcjed/__webpack_hmr net::ERR_FILE_NOT_FOUND複製程式碼
原因也就是webpack請求的時候根據當前頁面地址來的,沒想到還有 nw 這麼個環境
處理方法也簡單,更改 webpack-hot-middleware
的配置,讓其每次發請求的時候用__webpack_public_path__
或者全域性變數。
同時請注意path=__webpack_hmr
改hotClient
這一行程式碼為這樣子
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true&dynamicPublicPath=true&path=__webpack_hmr')複製程式碼
這樣配置的文件來源: webpack-hot-middleware
6) config/index.js
同時需要更改開發者模式下 assetsPublicPath 的配置,不然__webpack_public_path__
依然為/
module.exports = {
// ...
dev: {
env: require('./dev.env'),
port: 8080,
assetsSubDirectory: 'static',
assetsPublicPath: 'http://localhost:8080/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}複製程式碼
至此,一個完整的開發建構就出來,後面慢慢更新產品模式的打包建構。