we-pepper
v2.0.21
Published
wepiao front end solution
Downloads
43
Readme
Pepper
pepper 是一个基于 webpack 的打包工具,不依赖于具体项目,相反,它是诸多 RWE ( React & Webpack & ES6 ) 项目共同点的抽离。对 RWE 项目来说,开发环境和部署环境都是通用的,他们存在的唯一目的,就是方便代码的调试和打包。这就是 pepper 诞生的初衷。
现在,只需在RWE 项目的根目录下创建 pepepr.config.js
( pepper 的配置文件),就可具备初始 RWE 项目的所有功能。
关于 Yarn
pepper 可以通过 yarn 进行安装
// firstly: install yarn, may require your sudo privilege
npm install yarn -g;
// then install depends packages
yarn install;
// link and compile pepper
npm link;
// then you are done! enjoy pepper ;)
如何安装
gitlab 手动编译
# 克隆 pepper 仓库到本地目录(默认 pepper 即可) git clone [email protected]:FEI/pepper.git # 进入 pepper 目录 cd pepper # 安装运行时依赖 & 编译 npm link
npm 全局 ( depreacted & outdated) 此种方式后续会逐渐废弃
npm install we-pepper -g --registery http://npm.intra.wepiao.com
项目创建
| cli 命令 | 说明 |-------------------------------|---------------------------- | pepper init [name] | es6 & react-router | pepper init-redux [name] | es6 & react-router & redux | pepper init-rn [name] | react-native (演出票 DEMO)
目录结构一览
.
├── /dist/ # 代码打包目录
├── /node_modules/ # node依赖包
├── /src/ # 源码目录
│ ├── /pages/ # 页面
│ ├── /components/ # 公用组件
│ ├── /assets/ # 图片、字体资源
│ ├── /scss/ # 公用样式
│ └── /utils/ # 公用JS模块
├── pepper.config.js # pepper的配置文件
├── index.template.html # 首页HTML模版, 可选
└── package.json # 这个就不用说了吧
项目打包
| cli 命令 | 说明 |-------------------------|----------------------------------------------- | pepper start [-p PORT] | 本地调试,基于 start 配置 | pepper test | 运行测试代码, 基于 test 配置打包 | pepper pre | 基于 pre 配置打包,压缩 | pepper release | 基于 release 配置打包,压缩,移除 console 日志 | pepper library [mode] | 基于现有配置文件,将代码打包成 lib 库,可发布至 npm ,供其他项目使用, 使用参考
打包结果一览
➜ pepper pre
Hash: d72ff25390f520660578
Version: webpack 1.12.11
Time: 8205ms
Asset Size Chunks Chunk Names
js/shared-9f5500d8.js 34.7 kB 0, 3 [emitted] shared
js/home-1fb4ec5e.js 6.85 kB 1, 3 [emitted] home
js/vendor-5a9e0e26.js 131 kB 2, 3 [emitted] vendor
index.html 647 bytes [emitted]
[0] multi vendor 40 bytes {2} [built]
+ 194 hidden modules
项目测试
| 基于模块 | 说明 |-------------------------------------------------|---------------------------------------- | ava | 🚀 Futuristic JavaScript test runner | enzyme | JavaScript Testing utilities for React
测试功能正在开发中
配置文件
| 配置项 | 默认值 | 说明
|-------------------------|-------------- |-------------------------------------------------
| host | 0.0.0.0 | 调试IP,本地调试使用默认值即可
| port | 9527 | 端口,start 模式下,可通过 -p [PORT] 覆盖该项
| base | src | 代码根目录
| externals | {} | demo { '$': 'jQuery' }
| jshash | true | 是否启用 js 文件名字添加 hash 后缀
| build | dist | 打包目录,打包后的代码将放置到此处,与 base 同级
| static | 见示例配置 | 静态资源 CDN 域名设置,路径结尾包含/
代码中以 STATIC
引用, etc.. console.log(STATIC)
| api | 见示例配置 | API 路径设置,路径结尾不包含/
代码中以 API
引用
| globals | 见示例配置 | 更多全局变量设置,js代码中以配置项 key 的大写 KEY
形式引用,如果在首页模板中,用法则为{%=o.configs.KEY%}
| vendor | ['react', 'react-dom'] | 将指定的类库打包到 vendor-[hash].js中,建议常用的类库放到此处。此项不包含业务代码,不会经常变动此项,可充分利用缓存优势
| alias | 见示例配置 | 1) 路径别名 2) 模块化引用方式,去相对路径痛点
| alias_modules | 见示例配置 | 模块别名 , 比如使用 react-lite 替换 react
| devtool | source-map | 参见 webpack 调试选项
| template | 见示例配置 | html 模版配置
| template.title: | | 模版 document.title
| template.keywords | | 模版 meta keywords
, 默认为空
| template.description | | 模版 meta description
, 默认为空
| template.viewport | width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no | 模版 meta viewport
| viewport 配置
| template.favicon | | 模版 favicon
, 默认为空
| template.path: | | 设定自定义模版的的路径,会替换默认模版,可选。 有语法要求
| pages | pages | 程序入口,页面目录,默认为 pages/index
,可修改, 支持多 html 模版,详细见示例配置
| scss | scss | 公共样式目录,可修改
| assets | assets | 静态资源目录,可修改
| components | components | 页面间共享的组件目录,可修改(非共用组件,放置在当前页面目录即可)
| eslint | false | 是否启用 eslint , 默认关闭,如果启用该选项,请在项目根目录提供自己的 .eslintrc
| css_modules | false | 是否启用 CSS Modules, 默认关闭
| esmode | es6 | 模版代码风格,支持 es5
和 es6
, 默认为 es6
, 兼容 es7
| transfer_assets | false | 打包时是否 copy
asset目录,默认 false
| base64_image_limit | 1024 | 对所有小于该大小的图片启用 base64 转码, 默认 10240 (10k)
| transfer_assets | false | 打包时是否 copy
asset` 目录,默认 false
示例配置
{
"host": "0.0.0.0",
"port": "9527",
"base": "src",
"build": "dist",
"static": { // CDN domain, or just leave it blank if not using
"start": "/",
"test": "/",
"pre": "/",
"release": "/"
},
"globals": { // 配置全局变量,这里配置了 static_api 和 api 两个全局变量
// static api
"static_api": {
"start": "", // local api base entry
"test": "",
"pre": "", // online api base entry
"release": ""
},
"api": {
"start": "",
"test": "",
"pre": "",
"release": ""
}
},
"vendor": ["react", "react-dom"],
"alias": {
"wepiao": "components",
"scss": "scss"
},
"alias_modules": {
"react": "react-lite",
"react-dom": "react-lite"
},
"devtool": "source-map",
"template": {
"path": "index.template.html", //使用自定义模版
"title": "",
"keywords": "",
"description": "",
"viewport": "",
"favicon": "assets/images/favicon.ico"
},
"pages": "pages",
/* // multiple template config
*
* pages: {
* index: { entry: 'pages/index', template: 'index.template.html' },
* other: { entry: 'pages/other', template: 'other.template.html' }
* }
*/
"scss": "scss",
"components": "components",
"assets": "assets",
"eslint": false, // 如果启用该选项,请在项目根目录提供自己的 `.eslintrc`
"css_modules": false,
"transfer_assets": false,
"base64_image_limit": 10240,
"esmode": 'es6' // swith esmode on template creating, es5/es6, default to es6
}
默认HTML模版
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="keywords" content="webpack, react, es6, build tools"/>
<meta name="description" content="webpack auto build tools intergated with one command"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="format-detection" content="telephone=no"/>
{% if (o.htmlWebpackPlugin.files.favicon) { %}
<link rel="shortcut icon" href="{%=o.htmlWebpackPlugin.files.favicon%}">
{% } %}
{% for (var css in o.htmlWebpackPlugin.files.css) { %}
<link href="{%=o.htmlWebpackPlugin.files.css[css] %}" rel="stylesheet">
{% } %}
{% if(o.chunkManifest) { %}
<script>{%#o.chunkManifest%};</script>
{% } %}
<title>frontend-build-tools</title>
</head>
<body>
<div id="app">
</div>
{% for (var chunk in o.htmlWebpackPlugin.files.chunks) { %}
<script type="text/javascript" src="{%=o.htmlWebpackPlugin.files.chunks[chunk].entry%}"></script>
{% } %}
</body>
</html>
- 注: 首页模板支持pepper.configs.js配置的api, static, mode, globals等全局变量。具体用法:
<link rel="shortcut icon" href="{%=o.configs.STATIC%}assets/bundle.css">
<script>
if ("{%=o.configs.MODE%}" == 'release') {
he('send', 'error', {err: s.substr(0, 999)});
}
</script>
API
| cli 命令 | 说明
|-------------------------------|----------------------------
| pepper init [name] | es6 & react-router
| pepper init-redux [name] | es6 & react-router & redux
| pepper init-rn [name] | react-native (演出票 DEMO)
| pepper page [name] | 创建页面
| pepper component [name] | 创建组件
| pepper upgrade | 版本升级 (gitlab pull)
| pepper start [-p PORT] | 本地调试,基于 start 配置
| pepper test | 运行测试代码, 基于 test 配置打包, 可后缀 -s
启动服务
| pepper pre | 基于 pre 配置打包,压缩, 可后缀 -s
启动服务
| pepper release | 基于 release 配置打包,压缩,移除 console 日志, 可后缀 -s
启动服务
| pepper library [mode] | 基于 mode [test, pre, release] 模式将项目按照 umd 格式打包成类库,类库名称 package.json
name 属性制定, 使用参考
也可以这样玩耍 (项目目录下输入 pepper)
➜ pepper
? 选择要执行的任务:
项目打包
代码格式校验
开发调试
❯ 初始化新项目 (es5)
初始化新项目 (es6 & react & react-router)
初始化新项目 (es6 & react & react-router & redux)
初始化新项目 (react-native & redux)
(Move up and down to reveal more choices)
常见问题
clone 后的 pepper 要放到哪里?
一定不要放到项目目录下,一定不要放到项目目录下,一定不要放到项目目录下,(建议放到应用程序目录,pepper 也是个程序嘛)
程序入口在哪里?
在配置项中的 pages
有说明,它就是整个程序的入口,默认使用 pages/index
文件。这里定义了程序的路由配置,path='/' component={INITIAL_PAGE}
,INITIAL_PAGE
就是应用的首页
import PAGE from 'react-proxy?name=PAGE_NAME!./page_path
是什么意思 ?这个是使用 react-proxy-loader 对页面进行拆分,由于每一页面对应一个Router,从而实现了页面的按需加载。当然,如果不需要页面的懒加载功能,可以直接这样引用
import PAGE from './page_path'
怎么在组件或者页面中引用图片?
首先,图片、字体等静态资源要统一放到
assets
目录中去。 其次,确保pepper.cofig.js
中的alias
中有assets
的配置之后,对于 js 中的图片地址,要先 import IMAGE from
assets/paths/to/your/image
, 然后<img src={IMAGE} />
就可以了SCSS 中的图片引用,要这样处理
background-image: url(~assets/paths/to/your/image)
字体文件引用报错
对于本地字体文件的引用,请去除文件后缀名之后的所有参数(hash 或者 queryStr 之类的)
多个 html 文件
不同的页面入口文件,可指定不同的 html 模版
chunkManifest的异步加载模块crossOrigin属性问题
release打包后,项目需要异步加载模块时,如果pepper.configis.js的globals存在crossOrigin变量,则把crossorigin属性加到script中
效果如:
<script type="text/javascript" crossorigin="anonymous" charset="utf-8" async src="//mqqstatic.wepiao.com/tld/js/cinemas-e9243a4.js"></script>
具体配置:
globals:{ "crossOrigin": { "start" : "anonymous", "test" : "use-credentials", "pre" : "use-credentials", "release" : "anonymous" } }
. ├── [ 232] README.md ├── [ 170] dist ├── [ 547] mock.js ├── [1.8K] node_modules ├── [ 391] package.json ├── [2.8K] pepper.config.js ├── [ 238] src ├── [1.1K] template.html └── [ 687] test.html
pepper.config.js
配置多页面入口// custom default page dir "pages": { // 生成的 html 文件的名称 index: { // 入口文件路径,相对于 src 目录下 entry: 'pages/index', // 模版文件路径 相对于 根目录 template: 'template.html' }, test: { entry: 'pages/test', template: 'test.html' } },
最后打包生成不同的 html 文件 ( pepper release )
Hash: c55a6f52505a36434410 Version: webpack 1.13.2 Time: 7106ms Asset Size Chunks Chunk Names js/index-47dbd820.js 57.6 kB 0, 4 [emitted] index js/home-819f5bf8.js 10.2 kB 1, 4 [emitted] home js/test-d4588b46.js 500 bytes 2, 4 [emitted] test js/vendor-d10e59ab.js 131 kB 3, 4 [emitted] vendor js/manifest-e2ed8267.js 1.29 kB 4 [emitted] manifest index.html 1.95 kB [emitted] test.html 1.59 kB [emitted] [0] multi vendor 40 bytes {3} [built] + 239 hidden modules
pepper 怎么升级
墙裂建议采用 gitlab 本地安装,这种方式升级较容易(终端中执行:
pepper upgrade
,任意目录皆可)Start 模式下 替换 html 模版文件中的字符串
场景:html 文件中包含特定格式的字符串占位符,上线时该字符串由线上发布机替换成真实的值 问题:线下开发,无法处理字符串占位符替换问题,阻碍开发进程 解决方案:指定一个特定的文件,包含要替换的逻辑以及对应的值,每个 html 模版对应一个该文件,运行时做替换处理
pepper 配置如下:
单模版 html 配置:
"template": { "path": "src/template.html", // custom template path, omit it if your desire to use inner template "mock": "src/template.mock.js", // the replacement rules "favicon": "assets/images/favicon.ico" },
多模版 html 配置:
// custom default page dir "pages": { "index": { entry: "pages/index", template: "src/template.html", // target html to be replaced mock: "src/template.mock.js", // the replacement rules }, "share": { entry: "pages/share", template: "src/template.html", mock: "src/template.mock.js", } },
替换文件的规则:
// 多个数组 modules.exports = [ // 子数组,前者替换规则的正则表达式, 后者为要替换的值 [ /\[\[\[sSharePic\]\]\]/g, "http://wx.wepiao.com/favicon.ico" ], [ /\[\[\[sShareTitle\]\]\]/g, "微信电影票" ], [ /\[\[\[sShareContent\]\]\]/g, "娱票儿,微信电影、演出票" ], [ /\[\[\[appShareChannels\]\]\]/g, "1,3,4" ], ] // 没有使用键指对的原因在于,key 不能为正则表达式
注意:该规则只在开发(start)模式下有效,测试,预上线和线上由发布机做处理
关于用 pepper 打包公共组件库的说明
现在 pepper 支持将项目按照 umd 的格式,打包成公共类库,跨项目使用。这个是为了解决一些公共组件跨项目使用的问题。
- 按照 npm 的规范,将项目配置成也发布的格式。
- 在 pepper.config.js 中制定库的入口文件, 默认
src/index.js
├── demo
├── package.json
├── pepper.config.js
├── src
│ ├── Banner
│ ├── FullScreen
│ ├── Picture
│ ├── index.js
│ ├── style.scss
│ └── utils
└── yarn.lock
具体参见 Advertisement 项目配置
关于 npm 的常见问题
npm install
这个命令会拉取
package.json
的dependencies
,devDependencies
列表中罗列的依赖包,并存放到node_modules
中去。一般会在初次clone
项目时用到。还有就是,如果某次代码更新后,packages.json
中有变动,或者终端中提示未找到某个模块之类的错误,也要执行下npm install
npm install PACKAGE --save
指在项目中安装PACKAGE
依赖包,并保存到package.json
的dependencies
中去。npm install PACKAGE --save-dev
指在项目中安装PACKAGE
依赖包,并保存到package.json
的devDependencies
中去。--save
和--save-dev
的区别在于,前者是代码逻辑中的依赖(React),后者只是起辅助(代码校验,编译等等, 线上代码并不包含) 具体参考这里npm shrinkwrap
这个会锁定依赖包的版本,而不是在每次
npm install
时使用最新的patch version
举个例子,项目中依赖vision-ui@^1.2.11
,如果有新版[email protected]
,那在首次npm install
的时候就会下载[email protected]
而非[email protected]
。这个与 npm 升级策略有关。强烈建议开启此项。 具体参考这里