program-loader v0.1.1
vue项目转成原生小程序
喜迎中华人民共和国成立70周年~~~ 🎵我和我的祖国,一刻都不能分割🎵
前段时间接到一个项目改造任务,需要把Vue项目里的功能重写成原生小程序。(惊不惊喜,意不意外)
在公司里,这种功能保持不变但是需要写在不同平台上的问题,其实很多,我们不可能换一次平台,手写一次,耗时耗力在重复性高的工作中,难免会有错误。
最近看了看如何撸一个webpack-loader灵机一动,我们也可以写一个啊,还是用vue项目开发,打包时生成小程序的文件。这里,现在只开发到vue文件转小程序原生,css相对于简单很多只需要px转2px。而js就复杂很多了,放在Future完成了,有兴趣的小伙伴也可以加入一起开发啊~一起完成它~
为什么用webpack-laoder?
loader
用于对模块的源代码进行转换。loader
可以使你在 import或"加载"模块时预处理
文件。因此,loader类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。 ---摘自官方文档
在这里我用loader,是因为他有这么几个优点:
- loader 接收查询参数。用于对 loader 传递配置。
- loader 也能够使用 options 对象进行配置。
loader 运行在 Node.js 中,并且能够执行任何可能的操作。
接受参数我们可以自定义最后生成成什么平台的小程序。预处理,我们可以在打包前拿到文件内容利用vue的插件解析出template
,css
和 javascript
三个文件,从而进一步取处理。
第一节,我们先把项目搭起来~ let't Go !
安装
npm install program-loader
在vue项目中搭起环境
我自己在项目中创建了一个task文件,专门用来开发这个webpack-laoder,自己简单的配置了webpack。
接下俩简单介绍一下,里面3个文件的作用。
build.js
build.js用途就是调用wenpack输出我们小程序文件
const shell = require('shelljs')
const { resolve } = require('path')
const fs = require('fs')
const webpack = require('webpack')
const _ = require('lodash')
const r = url => resolve(process.cwd(), url)
const config = require('./config') //我们抽出的小程序主要的文件
const webpackConf = require('./webpack.conf') // webpack配置
const assetsPath = config.assetsPath
shell.rm('-rf', assetsPath)
shell.mkdir(assetsPath)
const renderConf = webpackConf
const entry = () => _.reduce(config.json.pages, (en, i) => {
en[i] = resolve(__dirname, '../src/components/', `HelloWorld.vue`) //需要转成小程序的文件的地址
return en
}, {}) //输出一个对象
renderConf.output = { //输出文件的配置
path: config.assetsPath,
filename: '[name].js'
}
renderConf.entry = entry()
// renderConf.entry.app = config.app
// 如果你不传入回调函数到 webpack 执行函数中,就会得到一个 webpack Compiler 实例。你可以通过它手动触发 webpack 执行器,或者是让它执行构建并监听变更。和 CLI API 很类似。Compiler 实例提供了以下方法
const compiler = webpack(renderConf) //导入的 webpack 函数需要传入一个 webpack 配置对象,当同时传入回调函数时就会执行 webpack
fs.writeFileSync(resolve(config.assetsPath, './app.json'), JSON.stringify(config.json), 'utf8')//一步写入文件小程序的app.json
const callback = (err, stats) => {
console.log('Compiler 已经完成执行。');
if (err) process.stdout.write(err) //如果有报错,就在控制台打印出报错
};
compiler.run(callback)
webpack.conf.js
webpack的配置项
const { resolve } = require('path') //方法会把一个路径或路径片段的序列解析为一个绝对路径。
const r = url => resolve(__dirname, url)
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin') //将单个文件或整个目录复制到构建目录
const ProgressBarPlugin = require('progress-bar-webpack-plugin') //打包时候在命令行里的进度条
const ExtractTextPlugin = require('extract-text-webpack-plugin') //打包的时候分离出文本,比如css,打包到单独的文件夹里
const extractSass = new ExtractTextPlugin({
filename: '[name].wxss'
})
const config = require('../config')
module.exports = {
devtool: false,
output: {
path: config.assetsPath,
filename: '[name].js'
},
resolve: {
alias: {
utils: r('../utils/utils')
}
},
resolveLoader: {
// 去哪些项目下寻找Loader,有先后顺序之分,这里是为了本地调试laoder方便
modules: ['node_modules', './loaders/'],
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: [
'latest'
]
}
},
{
test: /\.vue$/,
loader: 'program-loader', //这个就是我们变成的小程序laoder
options: {
dist: './program',
type:''
}
}
]
},
plugins: [
extractSass,
new CopyWebpackPlugin([
{
from : {
glob: 'pages/**/*.json',
to: ''
}
}, {
from: 'static',
to: 'static'
}
]),
new webpack.optimize.ModuleConcatenationPlugin(),//解释是启用作用域提升,webpack3新特性,作用是让代码文件更小、运行的更快
new ProgressBarPlugin()
]
}
config.js
这个文件是配置小程序生成的json文件,公共style等。
const { resolve } = require('path')
const r = url => resolve(__dirname, url)
const assetsPath = resolve(process.cwd(), './program')
module.exports={
"json":{ //通过这个配置小程序的页面
"pages":[
"pages/home/home",
],
"window":{
}
},
"style":{
url:r('./style/common.less'),
lang:'less'
},
"assetsPath": assetsPath,
}
运行就靠一行代码 node task/build.js