pepper-talks



pepper-talks

0 0


pepper-talks

front end build tools -- pepper

On Github Duan112358 / pepper-talks

Pepper

Wepiao FE Build Tools

duanhong@wepiaoDec 2015

export default () => (
    <FE-Developer name='段宏'>
        <Wepiao> Frontend Infrastructure Team @2015 </Wepiao>
        <Weidian> Frontend Team @2015 </Weidian>
        <Qfpay> Frontend @2014 </Qfpay>
    </FE-Developer>
)

blog@dhong.co

Front End Development

head
    link(rel="stylesheet" href="reset.css")
body
    div.content
    script(src="jquery.js")
    script(src="index.js")

HTML && CSS && JavaScript

How about that?

Ajax -> jQuery -> Bootstrap -> Angular -> React

Front End

CSS

CSS Preprocesser

LESS

Stylus

SASS

JavaScript

JS Modules

JS own problem

Compile To JS

our coding style

JS Modules

RequireJS

SeaJS

CommonJS

ES6 import

Compile to JS

CoffeeScript

TypeScript

JSX

Sum up

CSS preprocesser

Compile to JS

JS Modules Implementation

Have we done ?

How about Optimization ?

CSS Minify

JS Uglify

Image Compression

Request Combination

...

How to combine those together?

Build Automation

Grunt

Gulp

Browserify

Webpack

Grunt & Gulp

  • Tasked based

  • Organized by file

Browserify & Webpack

  • Entry based

  • Dependency Graph

Now , what we got ?

config, config, config...

complex dev ENV

really hard to begain with

I fucked up

what we really want ?

write a page

view in the browser

debug and coding

review ...

Just those...

FE is a Stuggle

After a long time struggle

Painful but Joyful

we create a wheel

Pepper

What's Pepper ?

???

We need such a pepper

图片来自fouber

So we create one

Based on Webpack

React

Webpack

Thanks Huxpro

Webpack - Module Bundler

(2014)

transforming, bundling, or packaging just about any resource or asset

Motivation

  • Compatibility (CommonJS, AMD, ES6...)

  • Code Splitting

  • Loaders & Plugins

  • Development Tools & Workflow

Using Loaders

// webpack.config.js
module.exports = {
    entry: './main.js',
    output: {
        filename: 'bundle.js'
    }{,
    module: {
        loaders: [{
            test: /\.js?x$/,
            loader: 'babel-loader'
        }]
    }}
}

Why only JavaScript?

There are many other static resources that need to be handled

require() static resources!

// Ensure the stylesheet is loaded
require('./bootstrap.css');

// get a URL or DataURI
var myImage = document.createElement('img');
myImage.src = require('./myImage.jpg');

They are part of dependency graph

require() anything!

// CSS Preprocesser
require('./style.less');
require('./anotherStyle.scss');

// Compile-to-JS Language
var myModule = require('./myModule.coffee');
var myTypedModule = require('./myTypedModule.ts');

Universal Module System

Sass & Images

var webpackConfig = {
    module: {
        loaders: [{
            test: /\.scss$/,
            loaders: 'style!css!sass'
        }, {
            test: /\.(png|jpg|svg)$/,
            loader: 'url?limit=20480' //20k
        }]
    }}
}
  • Deal with CSS problems

  • Inlining your images to DataURI

Using Plugins

var config = {
    entry: ['webpack/hot/dev-server', './app/main.js'],
    module: {
        loaders: [{
            test: /\.(js|jsx)$/,
            loaders: ['react-hot', 'babel']
        }]
    },
    plugins: [
        //Enables Hot Modules Replacement
        new webpack.HotModuleReplacementPlugin(),
    ],
};

React Hot Loader!

Code Splitting

split your codebase into “chunks” which are loaded on demand.

webpack is so powerful

we have a good time with webpack

.
├── node_modules
│   └── 61 modules
├── package.json
├── config.json
├── src
│   ├── assets
│   ├── components
│   ├── pages
│   └── scss
├── template.html
├── webpack.config.js
└── webpack.config.production.js

but, not so good

.
├── node_modules
│   └── 61 modules, dev 52
├── config.json
├── template.html
├── webpack.config.js
└── webpack.config.production.js

Too many Dependencies

Configuration still bleeding

how to resolve those ?

what about split dev out ?

➜  demo  tree -L 2
.
├── mock.js
├── node_modules
│   └── no dev modules
├── package.json
├── pepper.config.js
├── src
│   ├── assets
│   ├── components
│   ├── pages
│   └── scss
└── template.html

we found our way

About two weeks harkworking

pepper was born out

npm install we-pepper -g

➜  $  pepper
? 选择要执行的任务:  (Use arrow keys)
❯ 项目打包
  开发调试
  初始化新项目 (es5)
  初始化新项目 (es6)
  创建新页面
  创建新组件
  升级pepper

项目打包

pepper [test, pre, release]

开发调试

pepper start [-p PORT]

初始化新项目

pepper init proj_name

创建新页面

pepper page PAGE_NAME

创建新组件

pepper component COMPONENT_NAME

升级 Pepper

pepper ungrade

||

npm install we-pepper -g

so, How pepper works ?

About pepper.config.js

pepper.json no comments allowed

or

pepper.config.js

URL

// CDN domain, or just leave it blank if not using
"static": {
    "start"         :   "",                         // here use relative path
    "test"          :   "",
    "pre"           :   "http://static.wepiao.com/",// here use CDN domain
    "release"       :   "http://static.wepiao.com/" // here use CDN domain
},

// API base entry
// config `mock.js` for CROS solution
"api": {
    "start"         :   "",                         // local api base entry
    "test"          :   "",
    "pre"           :   "http://wx.wepiao.com",     // online api base entry
    "release"       :   "http://wx.wepiao.com"
}

split out resource and api

DEMO

// pepper start
console.log(API, STATIC); // '', ''

...

// pepper release
console.log(API, STATIC); // 'http://wx/wepiao.com', 'http://static.wepiao.com/'

bundle common libs

// third patry libs to bundle,
// like react-router, fetch
"vendor": ["react", "react-dom"],

alias relative path

// dir alias, could use globally, despite of CWD
"alias": {
    "scss"          :   "scss",
    "wepiao"        :   "components",
    "assets"        :   "assets",
    "utils"         :   "utils"
}

ignore the '../../..'

DEMO

require('assets/path/to/image')

import styles from 'scss/your/style/path'

import  API from 'utils/api'

About mock.js

data mock

    module.exports = [{
        path: /\/apis/,
        method: 'get',
        data: function(options) {
            return [{          // response data
                id: 1,
                first: '@FIRST',
            }, {
                id: 2,
                first: '@FIRST',
            }, {
                id: 3,
                first: '@FIRST',
            }]
        }
    }];

url proxy

    module.exports = [{
        path: '/search',
        proxy: 'http://github.com',
        pathRewrite: {
            '^/search': '/search/users'
        }
    }];

Question

Hey, don't be shy.

pepper

THE END

duanhong@wepiao