因爲常常使用vue開發移動端項目,每次須要vuex和移動端適配,每次須要本身手動新建vuex所需的js文件,使用vw進行移動端適配也須要安裝一大堆依賴,感受很麻煩,因此考慮本身寫了一個簡單的插件,能夠自動新建vuex須要的文件和適配所需的相關配置,順便熟悉一下新學的node。css
直接npm install ly-vue-util -g安裝依賴,在vue項目中直接輸入vue-util,就能夠選擇是否須要vuex還有是否須要使用單位vw; git地址: github.com/lyaaaa/ly-v…vue
首先新建了一個src文件,因爲插件內容不是不少,因此就只有一個Index.js和一個util.js一個放插件的核心代碼,一個是所須要的功能方法; 而後,安裝了幾個依賴 inquirer.js 和 shell.js。inquirer.js 是一個用戶與命令行交互的工具,由於這個插件是須要用戶來選擇相關的選項的,並且inquirer.js我的感受用起來比較簡單,下面是與用戶交互的相關代碼:node
inquirer
.prompt([{
type: 'confirm',
message: 'install vuex ?',
name: 'vuex',
default: 'Y'
},
{
type: 'list',
message: 'choose your unit ?',
name: 'units',
choices: ['px', 'vw']
},
{
type: 'input',
message: 'please input your width and height, eg: 375,667 ?',
name: 'flexWH',
default: '375,667',
when: function (answers) {
return answers.units === 'vw'
}
}
])
.then(answers => {
});
複製代碼
如今,基本上就能夠實現交互效果,answers中會返回一些用戶選擇的相關選項,而後再根據相關的選擇執行相關代碼; 這裏先說下 vuex的相關代碼,使用shell.js能夠直接執行shell命令,因此當用戶選擇使用vuex中,確定是先經過shell.js安裝一下vuex,可是隻有這個確定是不行的,還須要將我以前說的vuex相關的文件導入到Vue項目中的對應位置,這裏就用到了node的path和fs模塊,剛開始的時候我是直接手動寫了每一個js須要的內容,直接for循環而後新建js文件,fs模塊寫入相關代碼,可是這樣有個問題就是,代碼雖然寫入了,可是文件沒有自動格式化,中間會有不少空格,後來又想到了一個更好的方法,就是又新建了一個template文件夾,而後寫了一個store文件夾,裏面把須要的action.js mutation.js等等都直接寫入,而後直接將文件所有寫入對應位置,下面是處理vuex相關代碼git
// index.js __root__: process.cwd()
if (answers.vuex) {
shell.exec('npm install vuex --save');
var url = path.join(__root__, '/src/store');
var src = path.join(__dirname, '../template/store');
existsFile(src, url, copyFile);
}
// util.js
// 複製文件夾到指定目錄下
copyFile: function (src, dst) {
// 讀取目錄中的全部文件/目錄
fs.readdir(src, function (err, paths) {
if (err) {
throw err;
}
paths.forEach(function (path) {
var _src = src + '/' + path,
_dst = dst + '/' + path,
readable, writable;
stat(_src, function (err, st) {
if (err) {
throw err;
}
// 判斷是否爲文件
if (st.isFile()) {
readable = fs.createReadStream(_src);
writable = fs.createWriteStream(_dst);
readable.pipe(writable);
}
// 若是是目錄則遞歸調用自身
else if (st.isDirectory()) {
exists(_src, _dst, copyFile);
}
});
});
});
},
// 判斷文件夾是否存在,不存在須要先建立目錄
existsFile: function (src, dst, callback) {
fs.exists(dst, function (exists) {
if (exists) {
callback(src, dst);
} else {
fs.mkdir(dst, function () {
callback(src, dst);
});
}
});
},
複製代碼
這裏要注意 process.cwd() 和 __dirname 的區別,一個是項目的當前運行目錄,一個是代碼的目錄. 這個功能實現後,完成vw的適配代碼就相對簡單了不少,原理也是同樣,經過Node讀取並修改css配置文件,經過shell安裝所需依賴。相關代碼以下:github
// index.js __root__: process.cwd()
if (answers.units === 'vw') {
var wh = answers.flexWH.split(',')
shell.exec('npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S');
shell.exec('npm install cssnano-preset-advanced --save-dev');
flexUtilVW(parseFloat(wh[0]), parseFloat(wh[1]))
}
// util.js
// 配置 vw 單位
flexUtilVW: function (width, height) {
var url = path.join(__root__, '/.postcssrc.js');
var test = require(url);
var plugins = test.plugins;
var obj = {
"postcss-px-to-viewport": {
viewportWidth: width,
viewportHeight: height,
unitPrecision: 3,
viewportUnit: 'vw',
selectorBlackList: [],
minPixelValue: 1,
mediaQuery: false
},
"cssnano": {
preset: "advanced",
autoprefixer: false,
"postcss-zindex": false
}
}
test.plugins = Object.assign({}, plugins, obj);
console.log(test)
fs.writeFile(url, 'module.exports=' + JSON.stringify(test), 'utf8', (err) => {
if (err) throw err;
console.log('done');
});
}
複製代碼
上面基本是這個簡單插件的核心思路與代碼,目前還有一個問題就是vw配置只是能夠在vue-cli 2的版本搭建的vue項目能夠使用 vue-cli3的因爲配置路徑不一樣,因此不能夠使用,這也是我第一次寫的node相關的項目,代碼和思路確定有不少不足的地方,還但願大神們能給我更合理的建議。vuex