Have ideas to improve npm?Join in the discussion! »

    we-pepper

    2.0.21 • Public • Published

    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 git@gitlab.intra.wepiao.com: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
    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 模版代码风格,支持 es5es6 , 默认为 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
      

      Demo 地址

    • 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 的格式,打包成公共类库,跨项目使用。这个是为了解决一些公共组件跨项目使用的问题。

    1. 按照 npm 的规范,将项目配置成也发布的格式。
    2. 在 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.jsondependencies, devDependencies 列表中罗列的依赖包,并存放到 node_modules 中去。一般会在初次 clone 项目时用到。还有就是,如果某次代码更新后,packages.json 中有变动,或者终端中提示未找到某个模块之类的错误,也要执行下 npm install npm install PACKAGE --save 指在项目中安装 PACKAGE 依赖包,并保存到 package.jsondependencies 中去。 npm install PACKAGE --save-dev 指在项目中安装 PACKAGE 依赖包,并保存到 package.jsondevDependencies 中去。 --save--save-dev 的区别在于,前者是代码逻辑中的依赖(React),后者只是起辅助(代码校验,编译等等, 线上代码并不包含) 具体参考这里

    • npm shrinkwrap

      这个会锁定依赖包的版本,而不是在每次 npm install 时使用最新的 patch version 举个例子,项目中依赖 vision-ui@^1.2.11 ,如果有新版 vision-ui@1.2.12 ,那在首次 npm install 的时候就会下载 vision-ui@1.2.12 而非 vision-ui@1.2.11。这个与 npm 升级策略有关。强烈建议开启此项。 具体参考这里

    Install

    npm i we-pepper

    DownloadsWeekly Downloads

    1

    Version

    2.0.21

    License

    ISC

    Last publish

    Collaborators

    • avatar
    • avatar
    • avatar