摘要:增加文件這個文件主要做的事情就是整理出用的,然后再調(diào)用進(jìn)行打包在中增加打包入口增加下面這一行代碼在打包完成的回調(diào)中簡單部就完成了打包,是不是異常清晰和簡單。參見如果有就寫上新增這個文件就是用來打包下安裝包的。。。
閱讀本文需要一點 JS 基礎(chǔ)和閱讀的耐心,我特么自己寫完后發(fā)現(xiàn)這文章咋這么長啊。。。如果你認(rèn)真看完算我輸!
另我專門做了個 vue-nw-seed 項目,里面包含了我這篇文章里的所有的點和一些別的優(yōu)化,方便大家快速開發(fā)。
一、最小侵入性使用 vuejs-templates 建構(gòu) NW.js 應(yīng)用在 Vue 圈里,最方便的項目建構(gòu)方式應(yīng)該是 vue-cli ,這整個生態(tài)里面最便捷的又應(yīng)該是 webpack 這個模板。再對這個模板比較熟悉了后,就開始想能不能根據(jù)這個模板快速構(gòu)建我們需要的 NW.js 項目呢?
蛤蛤,答案當(dāng)然是可以的。
最開始的思路比較笨重,如果你時間多,可以去看看我以前的思路 用 vue2 和 webpack 快速建構(gòu) NW.js 項目(1) 2333。在我連續(xù)加班一個月后整出了我們 豆豆數(shù)學(xué) 第一版后,稍微有了點空閑時間,就重新翻看了一下 NW.js 的文檔,有點小發(fā)現(xiàn)啊。
Manifest Format 清單文件中的小發(fā)現(xiàn)
main
{String} which HTML page should be opened or which JavaScript file should be executed when NW.js starts.
You can specify a URL here. You can also specify just a filename (such as index.html or script.js) or a path (relative to the directory where your package.json resides).node-remote
{Array} or {String} Enable calling Node in remote pages. The value controls for which sites this feature should be turned on. Each item in the array follows the match patterns used in Chrome extension.
這個意思是說中說 main 字段可以寫一個 URL ,也能寫 index.html 或者 script.js 文件, node-remote 字段說允許哪些遠(yuǎn)程頁面調(diào)用 Node 方法。
這組合起來就可以完全無侵入的使用 vuejs-templates 建構(gòu) NW.js 應(yīng)用!
整體思路就是設(shè)置 package.json 的 main 字段為 vue 項目的起始地址,然后把 node-remote 設(shè)置為
先上個效果
依然推薦 nwjs/npm-installer
npm install nw --save-dev
網(wǎng)絡(luò)不要的情況下,請參考之前寫的文章中關(guān)于 用 npm 安裝 NW.js 部分。
2、配置 webpack相對于第一版,這次對于模板標(biāo)配的建構(gòu)配置改動相當(dāng)小。
把 build/webpack.base.conf.js 中新加個 target 字段就搞定。大概就是這樣
module.exports = { entry: { ... }, output: { ... }, target: "node-webkit", ... }
簡單吧。
3、修改 package.json添加或者修改 main 字段為你的 vue 項目啟動地址,再添加 node-remote 為
{ "name": "vue-nw-seed", "version": "0.1.0", // ... "main": "http://localhost:8080", "window": { "title": "vue-nw-seed", "toolbar": true, "width": 800, "height": 500, "min_width": 800, "min_height": 500, "resizable": true, "frame": true, "kiosk": false, "icon": "/static/logo.png", "show_in_taskbar": true }, "nodejs": true, "js-flags": "--harmony", "node-remote": "4、修改 npm run dev 打開瀏覽器為打開 NW.js" }
這一部應(yīng)該是最復(fù)雜的一步,但實際上,相當(dāng)簡單。
增加 build/dev-nw.js
var exec = require("child_process").exec var path = require("path") var fs = require("fs") var nwPath = require("nw").findpath() var rootPath = path.resolve(__dirname, "../") var packageJsonPath = path.resolve(rootPath, "./package.json") module.exports = runNwDev function runNwDev(uri = "") { if (uri && (uri + "").trim()) { tmpJson = require(packageJsonPath) tmpJson.main = uri fs.writeFileSync(packageJsonPath, JSON.stringify(tmpJson, null, " "), "utf-8") } var closed var nwDev = exec(nwPath + " " + rootPath, { cwd: rootPath }, function(err, stdout, stderr) { process.exit(0) closed = true }) nwDev.stdout.on("data", console.log) nwDev.stdout.on("error", console.error) // 退出時也關(guān)閉 NW 進(jìn)程 process.on("exit", exitHandle) process.on("uncaughtException", exitHandle) function exitHandle(e) { if (!closed) nwDev.kill() console.log(e || "233333, bye~~~") } }
并修改 build/dev-server.js 文件中打開瀏覽器的那部分代碼。
// when env is testing, don"t need open it if (autoOpenBrowser && process.env.NODE_ENV !== "testing") { require("./dev-nw")(uri) }
至此,整個開發(fā)建構(gòu)就完成了,是不是幾乎無侵入性。
二、打包 NW.js 應(yīng)用推薦使用官方的包 nw-builder ,雖然好久都沒咋更新過了。。。
整體思路 :先打包 vue 項目,再用 Node.js 整理形成一個 package.json 文件到 dist 目錄中去。再用 nw-builder 打包出 NW 應(yīng)用。
先看效果,增加信心。
npm install nw-builder --save-dev
這個過程僅僅是安裝了打包 NW 的包裝器,其要用到的 runtime 要在使用的時候才下載。
如果網(wǎng)絡(luò)不好。。。可以自己先想個辦法直接復(fù)制一份 runtime 到 cacheDir 目錄中。
2、增加 config配置大于約定,2333。
增加 manifest 要被整理的字段,最終從 ./package.json 整理到 ./dist/package.json 中。
增加 builder 字段,可以參照 nw-builder 文檔來配置。
// see http://vuejs-templates.github.io/webpack for documentation. var path = require("path") function resolve(dir) { return path.join(__dirname, "..", dir) } module.exports = { build: { // ... nw: { // manifest for nw // the fileds will merge with `./package.json` and build to `./dist/package.json` for NW.js // Manifest Format: http://docs.nwjs.io/en/latest/References/Manifest%20Format/ manifest: ["name", "appName", "version", "description", "author", { main: "./index.html" }, "window", "nodejs", "js-flags", "node-remote"], // see document: https://github.com/nwjs/nw-builder builder: { files: [resolve("./dist/**")], platforms: ["win32"], version: "0.14.7", flavor: "normal", cacheDir: resolve("./node_modules/_nw-builder-cache/"), buildDir: resolve("./output"), zip: true, winIco: resolve("./static/favicon.ico"), buildType: "versioned" } } }, dev: { //... } }3、增加 ./build/build-nw.js 文件
這個文件主要做的事情就是整理出 NW.js 用的 package.json,然后再調(diào)用 nw-builder 進(jìn)行打包
var exec = require("child_process").exec var path = require("path") var fs = require("fs") var util = require("util") var rootPath = path.resolve(__dirname, "../") // get config var config = require(path.resolve(rootPath, "config")) // `./package.json` var tmpJson = require(path.resolve(rootPath, "./package.json")) var manifestPath = path.resolve(config.build.assetsRoot, "./package.json") // manifest for `./dist/package.json` var manifest = {} config.build.nw.manifest.forEach(function(v, i) { if (util.isString(v)) manifest[v] = tmpJson[v] else if (util.isObject(v)) manifest = util._extend(manifest, v) }) fs.writeFile(manifestPath, JSON.stringify(manifest, null, " "), "utf-8", function(err, data) { if (err) throw err // start build app if (!config.build.nw.builder) return var NwBuilder = require("nw-builder") var nw = new NwBuilder(config.build.nw.builder) nw.build(function(err, data) { if (err) console.log(err) console.log("build nw done!") }) })4、在 ./build/build.js 中增加打包入口
增加下面這一行代碼在 webpack 打包完成的回調(diào)中
// start build nw.js app require("./build-nw.js")
簡單 4 部就完成了打包,是不是異常清晰和簡單。蛤
三、打包 windows 下的 setup.exe 文件這個部分,我之前也寫了一篇文章 打包NW.js應(yīng)用和制作windows安裝文件 里面有比較詳細(xì)的打包介紹。
但,在我們借助了 nw-builder 做了 NW 的打包后,僅僅打安裝包就比較簡單了,所以今天我就簡寫,節(jié)約大家的時間和生命。
主要思路:用 Node.js 操作 iss 文件,再借助官方推薦的 innosetup 進(jìn)行打包。
繼續(xù)錄一個 打包 exe 文件的 demo
npm install iconv-lite innosetup-compiler --save-dev2、創(chuàng)建 ./config/setup.iss 打包配置文件
踩坑注意,不要用 utf8 存這個文件,用 ansi 格式存這個配置文件, 不然打出來的安裝包是亂碼。
; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! ; This CWD is the directory where the `setup.iss`, pay attention to join the relative directory! ; 該執(zhí)行目錄為 `setup.iss` 所在的目錄,請注意拼接相對目錄 #define MyAppName "_name_" #define MyAppAliasName "_appName_" #define MyAppVersion "_version_" #define MyAppPublisher "_appPublisher_" #define MyAppURL "_appURL_" #define MyAppExeName "_name_.exe" #define OutputPath "_outputPath_" #define OutputFileName "_outputFileName_" #define SourceMain "_filesPath_\_name_.exe" #define SourceFolder "_filesPath_*" #define LicenseFilePath "_resourcesPath_license.txt" #define SetupIconFilePath "_resourcesPath_logo.ico" #define MyAppId "_appId_" [Setup] ; NOTE: The value of AppId uniquely identifies this application. ; Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={#MyAppId} AppName={#MyAppName} AppVersion={#MyAppVersion} AppVerName={#MyAppAliasName} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={pf}{#MyAppName} LicenseFile={#LicenseFilePath} OutputDir={#OutputPath} OutputBaseFilename={#OutputFileName} SetupIconFile={#SetupIconFilePath} Compression=lzma SolidCompression=yes PrivilegesRequired=admin Uninstallable=yes UninstallDisplayName={#MyAppAliasName} DefaultGroupName={#MyAppAliasName} [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce [Files] Source: {#SourceMain}; DestDir: "{app}"; Flags: ignoreversion Source: {#SourceFolder}; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs [Messages] SetupAppTitle={#MyAppAliasName} setup wizard SetupWindowTitle={#MyAppAliasName} setup wizard [Icons] Name: "{commondesktop}{#MyAppAliasName}"; Filename: "{app}{#MyAppExeName}"; Tasks: desktopicon Name: "{group}{#MyAppAliasName}"; Filename: "{app}{#MyAppExeName}" Name: "{group}uninstall {#MyAppAliasName}"; Filename: "{uninstallexe}" [Run] Filename: "{app}{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent
細(xì)心的你可能已經(jīng)發(fā)現(xiàn)了這里面好多 _name_ 之類的東西,這玩意將要被 Node.js 替換成項目配置的信息,不需要每次手動改寫這個復(fù)雜的 iss 文件。
2、繼續(xù)加配置那句話咋說的來著,配置大于約定。23333333
在 ./config/index.js 文件中加上 build.nw.setup 字段,來配置要打包出來的應(yīng)用的信息。
nw: { // ... setup: { issPath: resolve("./config/setup.iss"), // 就是上面那個 iss files: path.resolve("./output", tmpJson.name + " - v" + tmpJson.version), // 要打包的文件目錄 outputPath: resolve("./output/setup/"), outputFileName: "${name}-${version}-${platform}-setup", // 提供 name、version、platform 三個字段進(jìn)行自定義輸出文件名配置 resourcesPath: resolve("./build/setup_resources"), // 上面沒說的打包用的 license 和 logo。參見 https://github.com/anchengjian/vue-nw-seed/tree/master/build/setup_resources appPublisher: "vue-nw-seed, Inc.", appURL: "https://github.com/anchengjian/vue-nw-seed", appId: "{{A448363D-3A2F-4800-B62D-8A1C4D8F1115}" // 如果有就寫上 } }3、新增 ./build/build-win-setup.js
這個文件就是用來打包 windows 下安裝包的。。。
var innosetupCompiler = require("innosetup-compiler") var path = require("path") var fs = require("fs") var iconv = require("iconv-lite") var rootPath = path.resolve(__dirname, "../") // `./package.json` var tmpJson = require(path.resolve(rootPath, "./package.json")) // get config var config = require(path.resolve(rootPath, "config")) var setupOptions = config.build.nw.setup fs.readdir(setupOptions.files, function(err, files) { if (err) throw err files.forEach(function(fileName) { if (!~fileName.indexOf("win")) return const curPath = path.resolve(setupOptions.files, fileName) fs.stat(curPath, function(err, stats) { if (err || stats.isFile()) return if (stats.isDirectory()) { makeExeSetup(Object.assign({}, setupOptions, { files: curPath, platform: fileName })) } }) }) }) function makeExeSetup(opt) { const { issPath, files, outputPath, outputFileName, resourcesPath, appPublisher, appURL, appId, platform } = opt const { name, appName, version } = tmpJson const tmpIssPath = path.resolve(path.parse(issPath).dir, "_tmp.iss") return new Promise(function(resolve, reject) { // rewrite name, version to iss fs.readFile(issPath, null, function(err, text) { if (err) return reject(err) let str = iconv.decode(text, "gbk") .replace(/_name_/g, name) .replace(/_appName_/g, appName) .replace(/_version_/g, version) .replace(/_outputPath_/g, outputPath) .replace(/_outputFileName_/g, getOutputName(outputFileName, { name, version, platform })) .replace(/_filesPath_/g, files) .replace(/_resourcesPath_/g, resourcesPath) .replace(/_appPublisher_/g, appPublisher) .replace(/_appURL_/g, appURL) .replace(/_appId_/g, appId) fs.writeFile(tmpIssPath, iconv.encode(str, "gbk"), null, function(err) { if (err) return reject(err) // inno setup start innosetupCompiler(tmpIssPath, { gui: false, verbose: true }, function(err) { fs.unlinkSync(tmpIssPath) if (err) return reject(err) resolve(opt) }) }) }) }) } function getOutputName(str, data) { return str.replace(/${(.*?)}/g, function(a, b) { return data[b] || b }) }4、再配置這個打包的入口
在我們上文提到的打包 NW 應(yīng)用的那個文件中 ./build/build-nw.js 中的最后打包完成的回調(diào)里加個調(diào)用入口
// build windows setup if (config.build.noSetup) return if (~config.build.nw.builder.platforms.toString().indexOf("win")) require("./build-win-setup.js")
這次簡潔吧,4 部就完成了打包。
來看效果。
原文持續(xù)更新: https://github.com/anchengjian/anchengjian.github.io/blob/master/posts/2017/vuejs-webpack-nwjs-2.md,同時,如果對您有用,幫我點個 star 吧,寫這玩意不容易啊。
如果你真的看到這兒了,我也就輸了。。。
那就順便看看 vue-nw-seed 這個項目吧,里面包含了我這篇文章里的所有的點和一些別的優(yōu)化。
希望還有其他需求的朋友可以提 issue 或者私信討論
謝謝!您的支持是我繼續(xù)更新下去的動力。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/82331.html
摘要:再用使用進(jìn)行圖標(biāo)替換,建議尺寸是。同時為其添加管理員權(quán)限。用把之前臨時放在中的包拷貝到目錄,再根據(jù)文件寫更新信息到中。這兒應(yīng)該可以優(yōu)化,下載到用戶數(shù)據(jù)目錄,或者其他臨時目錄。 打包NW.js應(yīng)用和制作windows安裝文件 更新:此文章部分技術(shù)點已落后,可以查看 最新文章 這可能是中文史上最詳細(xì)的 NW.js 打包教程 本文適應(yīng)有一定 js 基礎(chǔ),第一次玩 windows 下 s...
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認(rèn)命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
閱讀 1382·2021-09-22 10:02
閱讀 1862·2021-09-08 09:35
閱讀 4044·2021-08-12 13:29
閱讀 2594·2019-08-30 15:55
閱讀 2257·2019-08-30 15:53
閱讀 2295·2019-08-29 17:13
閱讀 2753·2019-08-29 16:31
閱讀 2948·2019-08-29 12:24