Score
0
Watch 8 Star 21 Fork 1

K. / webpack-miniprogram-pluginJavaScriptMIT

Join us
Explore and code with more than 2 million developers,Free private repositories !:)
Sign up
webpack微信小程序开发/打包插件,提供多环境的微信小程序开发/打包环境,实现开发/测试/产品模式的分离,支持不同开发用户自定义的小程序配置文件,通过 webpack.DefinePlugin 可以轻松解决不同环境下的配置分离。 spread retract

Clone or download
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README.md

webpack-miniprogram-plugin

Npm version

介绍

webpack微信小程序开发/打包插件,提供多环境的微信小程序开发/打包环境,实现开发/测试/产品模式的分离,支持不同开发用户自定义的小程序配置文件,通过 webpack.DefinePlugin 可以轻松解决不同环境下的配置分离。

主要特性:

  1. 该插件理论上兼容所有前端已知开发环境,开发者可配置成自己需要的开发环境,如:typescript,各种 Babel 的转译插件,SASS/LESS/Stylus,PostCSS等。
  2. 支持小程序所有的模式,wxs、template、component
  3. 支持分离开发/测试/产品环境,借用 webpack.DefinePlugin ,可以轻松实现多环境(分离不同的appid,接口base url)打包,再也不用担心上传错线上版本了。
  4. 不再局限于原有的 app.json 和 project.config.json ,真正做到每个开发者可以拥有自己的配置,能迅速提升你小程序项目的代码格局。

更新说明

1.0.3

  • 增加对已经从 json 中移除的 page 和 component 的 chunk 移除(包括对应的 assets)。
  • 优化 seekApp() 的入口。
  • 去掉默认的 sitemap.json ,转为根据 app.json 探测。

1.0.4

  • 插件 options 增加一个 mockMain 参数,创建一个模拟入口,来替代 main ,用于兼容一个小程序项目多个开发者参与,需要有不同的配置入口。对应的 json-loader 的写法,参考如下:
{
	test: /\.(json)$/,
	type: 'javascript/auto',
	use:  {
		loader:  "file-loader",
		options: {
			name: (filename) => {
				const path = replaceDS(pathUtil.relative(srcPath, filename));
				const reg = /app.(([a-z0-9-_]+).json)$/; // 假定我的项目中自定义的 app.json 文件为:app.custom.json
				if (path.match(reg)) {
					return path.replace(reg, 'app.json'); // 还原成 app.json 输出
				}
				return path;
			},
		},
	}
}

1.0.5

  • 修正 tabBar 解析的bug

安装说明

npm install webpack-miniprogram-plugin
// or
yarn add webpack-miniprogram-plugin

使用示例

具体参考 test/webpack.config.js 文件。

module.exports = {
	output: {
		libraryTarget: 'var', // 必须
	},
	target: 'node', // 必须
	plugins: [
		new MiniProgramPlugin(src, dist, options),
	]
};

options 的参考:


const options = {
	main:                'app.json',
	mockMain:            'app.my.json', // 创建一个模拟入口
    debug:               false,
    assets:              'assets',
    assetsChunkName:     '__assets_chunk_name__',
    bootstrapModuleName: 'bootstrap.js',
    // 公共附件后缀名,以 object 结构,如果要去掉某类文件,value 取 false
    exts:                {
        json: true,
        wxml: true,
        wxss: false,
    },
    // 脚本后缀名
    scriptExts:          {js: true},
    // 需要检查 io stat 的文件后缀,wxss 不是必选项,可能存在 page 或者 component 没有 wxss 文件
    checkStatExts:       {wxss: true},
    // app.js - app.json 的特定附加文件。
    app:                 {
        exts:  {wxml: false},
        // 附加文件
        files: [ // 不附加文件的话,files: false
            'sitemap.json', 'project.config.json',
        ],
    },
    // page 范围内的设定
    page:                {
		// 使用公共的后缀文件名
        // exts: {wxml: true},
        files: [],
    },
    // component 范围内的设定
    component:           {
        // exts: {wxml: true},
        files: [],
    },
    // 自定义路径匹配指定附加文件
    custom:              {
		// 指定 pages/index/index 的附加设定
        'pages/index/index': {
         	files: ['ok.json'],
        },
    },
}

引入依赖的路径写法

开发中引入 js 的路径,请严格遵照 npm 的标准,当前目录下的文件,应该是 require('./mobx') 或者 require('./any-module')require('loadsh') 表示引入 node_modules 下的 module。否则会导致 webpack 编译处理 js 的依赖关系时报错。

component 支持绝对路径和相对路径的两种写法:../../components/hello/world/components/hello/world

已经支持检索 app.json 中的 pages, subPackages, tabBar ,以及各个 json 中定义的 useComponents 字段。

样式文件

通过JS引入的模式(推荐)

样式文件,推荐在对应的 js 文件中引入(require 或 import),这样的好处是,可以使用 mini-css-extract-pluginextract-css-chunks-webpack-plugin ,来打包分离成对应的 wxss 文件,最终输出的效果更好。

loaders 可以参照如下的配置:

module.exports = {
	module: {
		rules: [
			{
                test: /\.styl$/,
                use:  [MiniCssExtractPlugin.loader, 'css-loader', 'stylus-loader'],
            },
            {
                test: /\.(css|wxss)$/,
                use:  [MiniCssExtractPlugin.loader, 'css-loader'],
            },
		]
	}
}

复制wxss模式

如果你希望插件对待 wxss 文件时,作为附加文件的模式处理的话,也是可以的,需要做如下的设置:

const path = require('path');

module.exports = {
	module: {
		rules: [
            {
                test: /\.(wxss)$/,
                use:  {
                	loader: 'file-loader',
                	options: {
                		name: (filename) => replaceDS(path.relative(srcPath, filename)), // 文件名路径名转换
                	},
                },
            },
		]
	},
	plugins: [
        new MiniProgramPlugin(src, dist, {
        	exts: {
        		wxss: true, // 开启 wxss 作为附件打包
        	}
        }),
    ]
};

附上实际项目 webpack 配置

本项目的一个出发点,就是为了能够彻底的活用 webpack 自身强大的可定制化功能,不考虑做脚手架,将配置内定,所以以下配置内容可能略微硬核。


const src = 'src';
const srcPath = pathUtil.resolve(process.cwd(), src);

// 转路径的分隔符号,主要针对windows
const replaceDS = (path) => path.replace(/[\\/]+/g, '/');

const options = { 
    // 指定以一个用户自己的 app.user.json 来替代 app.json,也是为了隔离不同用户版本、不同打包环境
    // 这样能彻底的使得参与项目的开发者,只需要关注自己那部分配置即可
    mockMain: 'app.user.json',
    app: {
        files: [ // 指定App的附加文件 
            // 使用自定义的 project.config.json 来提供默认项目配置 ,确保开发环境和发布环境分离,
            // 这样可以做到每个开发者使用自己的配置,或者是同一个项目可以打包成多个项目
            'project.config.dev.user.json', 
            // wxs 文件支持
            'wxs/utils.wxs', 
        ] 
    }
};

// webpack 的配置
const webpackConfig = {
    mode:         env === 'development' ? 'development' : 'production',
    entry:        {
        app: [`./${src}/app.js`],
    },
    output:       {
        filename:      '[name].js',
        libraryTarget: 'var',
        path:          pathUtil.resolve(__dirname, dist),
    },
    target:       'node',
    module:       {
        rules: [
            // 传统 js 的 babel 转译
            {
                test: /\.(js)$/,
                use:  [
                    {
                        loader:  'babel-loader',
                        options: {
                            presets: ['@babel/env'],
                            plugins: [
                                ['@babel/plugin-proposal-decorators', {
                                    "legacy": true,
                                }],
                                ['@babel/plugin-proposal-class-properties', {
                                    "loose": true,
                                }],
                                '@babel/plugin-transform-modules-commonjs',
                                '@babel/plugin-transform-block-scoping',
                                '@babel/plugin-transform-computed-properties',
                                '@babel/plugin-proposal-object-rest-spread',
                            ],
                        },
                    },
                ],
            },
            // 图片处理
            {
                test: /\.(png|jpg)$/,
                use:  {
                    loader:  "file-loader",
                    options: {
                        name: (filename) => {
                            return replaceDS(pathUtil.relative(srcPath, filename));
                        },
                    },
                },
            },
            // json 文件处理
            {
                test: /\.(json)$/,
                type: 'javascript/auto', // 新版webpack对json处理方式不同了,需要加这一句
                use:  {
                    loader:  "file-loader",
                    options: {
                        name: (filename) => {
                            const path = replaceDS(pathUtil.relative(srcPath, filename));
                            // 以下就是将 mock 的 json 文件,替代为实际有效的 app.json 和 project.config.json 来输出
                            const appReg = /app.(([a-z0-9-_]+).json)$/; // 假定我的项目中自定义的 app.json 文件为:app.custom.json
                            const projectReg = /project.config.([a-z0-9-_]+)(.([a-z0-9-_]+))?.json$/;
                            if (path.match(appReg)) {
                                return path.replace(appReg, 'app.json'); // 还原成 app.json 输出
                            }
                            if (path.match(projectReg)) {
                                return path.replace(projectReg, 'project.config.json');
                            }
                            return path;
                        },
                    },
                },
            },
            // wxml
            {
                test: /\.(wxml)$/,
                use:  {
                    loader:  "file-loader",
                    options: {
                        name: (filename) => {
                            return replaceDS(pathUtil.relative(srcPath, filename));
                        },
                    },
                },
            },
            // wxs 文件 也用 babel 来处理
            {
                test: /\.(wxs)$/,
                use:  [
                    {
                        loader:  "file-loader",
                        options: {
                            name: (filename) => {
                                return replaceDS(pathUtil.relative(srcPath, filename));
                            },
                        },
                    },
                    {
                        loader:  'babel-loader',
                        options: {
                            presets: ['@babel/env'],
                            plugins: [
                                ['@babel/plugin-proposal-decorators', {
                                    "legacy": true,
                                }],
                                ['@babel/plugin-proposal-class-properties', {
                                    "loose": true,
                                }],
                                '@babel/plugin-transform-modules-commonjs',
                                '@babel/plugin-transform-block-scoping',
                                '@babel/plugin-transform-computed-properties',
                                '@babel/plugin-proposal-object-rest-spread',
                            ],
                        },
                    },
                ],
            },
            // 这个项目使用了 stylus
            {
                test: /\.styl$/,
                use:  [MiniCssExtractPlugin.loader, 'css-loader', 'stylus-loader'],
            },
            // 一般的 css
            {
                test: /\.(css|wxss)$/,
                use:  [MiniCssExtractPlugin.loader, 'css-loader'],
            },
        ],
    },
    plugins:      [
        // 这里主要是因应不同 env 混入不同的 JS 常量,比如 API 地址,请参考 webpack/DefinePlugin 
        webpackPredef(env, predef.webpack, env.custom), 
        // 这里主要是因应不同的 env 的 stylus 全局常量,比如 CDN base url,请参考 stylusLoader.OptionsPlugin。
        new stylusLoader.OptionsPlugin({
            default: {
                use: [stylusPredef(env, predef.stylus)], 
            },
        }),
        new MiniProgramPlugin(src, dist, options),
        new MiniCssExtractPlugin(
            {
                filename: "[name].wxss",
            },
        ),
    ],
    devtool:      'inline',
    optimization: {
        splitChunks: {
            cacheGroups: {
                // src/utils, src/lib, src/model, src/store, src/actions, node_modules 路径下的代码,合并打包成一个独立的 lib.js 文件
                modules: {
                    test:      /([\\/](utils|lib|model|store|actions|node_modules)[\\/])/,
                    name:      'lib',
                    minSize:   0,
                    minChunks: 1,
                    chunks:    'all',
                },
            },
        },
    },
};

Comments ( 2 )

Sign in for post a comment

JavaScript
1
https://gitee.com/janpoem/webpack-miniprogram-plugin.git
git@gitee.com:janpoem/webpack-miniprogram-plugin.git
janpoem
webpack-miniprogram-plugin
webpack-miniprogram-plugin
master

Help Search