微信小程序因为其便捷的使用方式,以极快的速度传播开来吸引了大量的使用者。市场需求急剧增加的情况下,每家互联网企业都想一尝甜头,因此掌握小程序开发这一技术无疑是一名前端开发者不可或缺的技能。但小程序开发当中总有一些不便一直让开发者诟病不已,主要表现在:
初期缺乏方便的npm包管理机制(现阶段确实可以使用npm包,但是操作确实不便)
不能使用预编译语言处理样式
无法通过脚本命令切换不同的开发环境,需手动修改对应环境所需配置(常规项目至少具备开发与生产环境)
无法将规范检查工具结合到项目工程中(诸如EsLint、StyleLint的使用)
有了不少的问题之后,我开始思考如何将现代的工程化技术与小程序相结合。初期在社区中查阅资料时,许多前辈都基于gulp去做了不少实践,对于小程序这种多页应用来说gulp的流式工作方式似乎更加方便。在实际的实践过后,我不太满意应用gulp这一方案,所以我转向了对webpack的实践探索。我认为选择webpack作为工程化的支持,尽管它相对gulp更难实现,但在未来的发展中一定会有非凡的效果,
实践
我们先不考虑预编译、规范等等较为复杂的问题,我们的第一个目标是如何应用webpack将源代码文件夹下的文件输出到目标文件夹当中,接下来我们就一步步来创建这个工程项目:
/* 创建项目 */ $ mkdir wxmp-base $ cd ./wxmp-base /* 创建package.json */ $ npm init /* 安装依赖包 */ $ npm install webpack webpack-cli --dev
安装好依赖之后我们为这个项目创建基础的目录结构,如图所示:
上图所展示的是一个最简单的小程序,它只包含app全局配置文件和一个home页面。接下来我们不管全局或是页面,我们以文件类型划分为需要待加工的js类型文件和不需要再加工可以直接拷贝的wxml、wxss、json文件。以这样的思路我们开始编写供webpack执行的配置文件,在项目根目录下创建一个build目录存放webpack.config.js文件。
$ mkdir build $ cd ./build $ touch webpack.config.js
/** webpack.config.js */ const path = require('path'); const CopyPlugin = require('copy-webpack-plugin'); const ABSOLUTE_PATH = process.cwd(); module.exports = { context: path.resolve(ABSOLUTE_PATH, 'src'), entry: { app: './app.js', 'pages/home/index': './pages/home/index.js' }, output: { filename: '[name].js', path: path.resolve(ABSOLUTE_PATH, 'dist') }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: ['@babel/plugin-transform-runtime'], }, }, } ] }, plugins: [ new CopyPlugin([ { from: '**/*.wxml', toType: 'dir', }, { from: '**/*.wxss', toType: 'dir', }, { from: '**/*.json', toType: 'dir', } ]) ] };
在编写完上述代码之后,为大家解释一下上述的代码究竟会做些什么:
入口entry对象中我写了两个属性,意在将app.js和home/index.js作为webpack的构建入口,它会以这个文件为起始点创建各自的依赖关系,这样当我们在入口文件中引入其他文件时,被引入的文件也能被webpack所处理。
module中我使用了babel-loader对js文件进行ES6转换为ES5的处理,并且加入了对新语法的处理,这样我们就解决了在原生小程序开发中总是要反复引入regenerator-runtime的问题。(这一步我们需要安装@babel/core、@babel/preset-env、@babel/plugin-transform-runtime、@babel/runtime、babel-loader这几个依赖包)
使用copy-webpack-plugin来处理不需要再加工的文件,这个插件可以直接将文件复制到目标目录当中。
我们了解完这些代码的实际作用之后就可以在终端中运行webpack --config build/webpack.config.js命令。webpack会将源代码编译到dist文件夹中,这个文件夹中的内容就可用在开发者工具中运行、预览、上传。
优化
完成了最基础的webpack构建策略后,我们实现了app和home页面的转化,但这还远远不够。我们还需要解决许多的问题:
页面文件增多怎么办,组件怎么处理
预期的预编译如何做
规范如何结合到工程中
环境变量怎么处理
接下来我们针对以上几点进行webpack策略的升级:
页面与组件
一开始我的实现方法是写一个工具函数利用glob收集pages和components下的js文件然后生成入口对象传递给entry。但是在实践过程中,我发现这样的做法有两个弊端:
当终端中已经启动了命令,这时候新增页面或组件都不会自动生成新的入口,也就是我们要重跑一遍命令。