Neighborly Package Megalodon

    webpack-papa-script

    3.3.5 • Public • Published

    webpack-papa-script

    Build Status Coverage Status npm

    webpack-papa-script 是一个帮助前端开发更轻易地执行从开发到部署的工程化工具。

    它是一个前端多页面、多个项目集成的解决方案, 方便部署大量短期性的页面, 例如大量的活动推广专题。方便集成共用组件, 快速部署, 免去频繁执行依赖包的安装。

    特点

    • 基于 webpack v3, 贴紧webpack的生态
    • 蜂巢式的大项目,可任意创建小项目
    • 可单独或批量编译小项目,无需整个蜂巢项目进行编译
    • 批量编译时,自动识别所有项目
    • 自动识别页面入口
    • 相互独立的小项目可共用组件代码
    • 小项目可注入非 webpack 的公共代码包的引用, 公共包更新即对整个蜂巢项目起效
    • 便捷的业务环境切换
    • 灵活的项目部署配置
    • 灵活的开发环境
    • 快速部署
      • 可通过模版创建小项目
      • 集成了自动上传 ftp

    如何使用

    创建一个项目

    安装一个工具包

    npm i create-webpack-papa -g

    创建一个命名为 "proj-hive" 的站点项目

    create-webpack-papa create proj-hive

    等待依赖文件自动安装完成后, 进入项目, 即可使用 webpack-papa-script 的各种功能。

    cd proj-hive

    开发一个小项目

    创建一个命名为 "my-proj1" 单页初始小项目

    npm run create my-proj1

    对 my-proj1 进行本地开发

    npm run watch my-proj1

    部署上线代码

    npm run build my-proj1

    其他功能参考详细的cli命令

    功能介绍

    cli命令

    通用地, 命令采用npm run foo模式, foo代表具体的命令名称, 后面可接其他参数。一些参数内容是与papa.config.js的配置对应的。

    功能 例子 说明
    创建新小项目 npm run create foo 创建一个foo小项目。支持层级的目录:假如是src/2018/abc, 则把foo换为2018/abc
    选用特定的模版创建项目 npm run create foo t min 模版使用src/_template_min (默认模版是_template_def)
    开启本地开发 npm run watch path/to/foo path/to/foo 代表src/下的文件夹
    生成部署代码 npm run build path/to/foonpm run build path/to/foo,path/to/bar 编译目录path/to/foo的代码; 可以指定多个位置, 以,间隔。默认是部署config.productEnvType指定的模式编译; 具体的编译效果请看具体介绍
    批量生成部署代码 npm run build-all 自动查找src/下的所有的项目, 依次自动编译所有。
    设置批量生成的范围 npm run build-all scope path/to/foo 自动查找src/path/to/foo下的所有的项目, 依次自动编译所有;同build命令, scope的值也可以包含多个, 以,间隔。
    选择部署环境 npm run build foo test proconfig.deployEnvType中定义的key值, 默认是test\|pre\|pro.
    上传ftp npm run build foo test unpm start u foo foo在test模式编译后, 立即上传; 或指定上传的项目。(上传目录在config.localAssetPath设定。)
    生成公共资源 npm run deploy-static ./resource/js打包📦, 生成脱离webpack的公共代码包到./resource/bundle, 并把./resource/bundle的所有资源分发到config.deployEnvType配置的目录上(watch命令也会自动执行资源分发)
    设置前端的环境变量 npm run watch foo mode pro 把本地开发的代码的环境切换为pro的环境。为了避免误操作, 只有在config.developEnvType设置的环境下才能使用mode(watch即为该环境)。假如确实需要在其他环境切换, 可以把mode换为hard-mode
    强制编译环境为production npm run watch foo p 一般不需要使用, 某些情况为了调试或测试可用。此例子可把本地开发的编译效果改为像build那样
    强制编译环境为development npm run build foo d 一般不需要使用, 某些情况为了调试或测试可用。效果与p相反。

    build的介绍

    webpack-papa-script 有非常灵活的编译功能, build的操作可以针对一个或多个或一个范围内的所有项目, 详见使用build命令

    此外我们可以在项目下的papa.config.js自定义build的各项配置, 如:

    使用build命令

    先假设一个papa项目上有以下这样的目录结构, 它含有三个小项目foo,bar/baz,bar/qux

      |-build
      |-dist
      |-node_modules
      |-resource
      |-src
      |---foo
      |-----index.js
      |-----index.html
      |---bar
      |-----baz
      |-------index.js
      |-------index.html
      |-----qux
      |-------index.js
      |-------index.html

    npm run build 后面接需要build的目标即可, 目标是一个基于项目目录src下的子目录, 如:

    • npm run build foo 代表编译src/foo这个项目,

    • npm run build bar/baz 代表src/bar/baz这个项目。

    目标可以设置为多个, 一个命令build多个项目。用,隔开:

    • npm run build foo,bar/baz 同上面两条命令分别执行的效果。

    目标可以设置为一个范围内的所有小项目, 如:

    • npm run build-all 代表编译src下的所有项目。
    • npm run build-all scope bar 代表编译src/bar下的所有项目, 按照以上的例子, 则是bar/bazbar/qux

    同样, 指定的范围也可以包含多个, 用,隔开。(注意例子中的foo本身是一个项目, 用scope是不能识别的)

    编译模式的定义

    编译模式分了两个概念, 一个是前端环境, 一个是编译模式。我们可以通过papa.config.js定义这些配置, 然后在命令行可以使用配置里所定义的名称。

    前端环境

    我们上线一个项目前通常需要经过几个过程, 如本地开发环境, 测试环境, 预发布环境等。我们通过papa.config.js定义这些前端环境, 并且将这些环境变量注入到前端代码里。相关的属性例子如下:

    deployEnvType key值定义有哪些环境, 值为编译的输出目录。如以下定义了 test|pre|pro 3个。

      deployEnvType:{
          test: 'build/activity',
          pre: 'dist/pre',
          pro: 'dist/pro'
      }

    deployEnvMapFetch 可以定义环境对应的前端环境变量, 该值会注入编译后的代码里。

      deployEnvMapFetch: {
          test: 'test',
          pre: 'pre',
          pro: 'produce'
      },

    frontendConfCode 就是注入的js代码模版, 它接收两个变量, 其中一个是mode即为前端环境变量。详细例子参考使用方法生成的papa.config.js 例子。

    有了这些配置后, 我们就可以在命令中指定我们要使用哪一个环境:

    npm run build foo [test|pre|pro]

    假如我们不指定环境的话, 它会自动选取 papa.config.js 的productEnvType定义的环境。

    编译模式

    固定了两种:开发模式和发布模式 我们可以用developEnvType定义上文中deployEnvType里的哪个前端环境为开发模式, 其它则自动作为发布模式:

      developEnvType:{
          deploy: 'test',
          fetch: 'test'
      }

    deploy 是环境的命名, 需要是deployEnvType中的一个key值; fetch 是前端环境变量, 跑watch命令时会使用这个值, 一般上与deployEnvMapFetch对应的一致即可。

    运行watch时, webpack的devtool#inline-source-map。 运行build时, 假如前端环境等于developEnvType的定义, 则devtooleval。其他情况则不声明 devtool。 当然可以通过papa.config.jswebpackConfig强制改写webpack配置属性。

    编译代码的输出目录

    编译输出位置即上文的前端环境提到的deployEnvType中定义。

    定义如何识别项目

    项目识别的参考值定义在 papa.config.js, 当目录中含有projContainsOneOf的值, 就识别为项目, 其中, 假如该目录拥有proj.json, 则识别为一个多页项目, 其它情况就是单页项目。

    具体介绍如下:

    参数名 默认值 描述
    projContainsOneOf ['m', 'pc', 'proj.json', 'config.json'] 辨别一个项目时, 只要一个文件夹里面包含此属性定义的文件或文件夹名, 则认定它为一个项目。(无论单独页面还是多页面)
    projScanExclude ['modules','components', 'img', 'js'] 获取所有项目时, 排除以下这些文件夹里面的内容
    entryInclude ['index.js', 'index.html'] 入口文件夹必须包含这些文件。一般不要更改这个值, 其中包含 index.js, webpack才能正常编译
    commSingleProjSubPage ['m', 'pc'] 可以定义通用的, 每个小项目可以默认包含这些子页面, 它们共享config.json, 无需每个这种页面都添加 多页项目识别文件proj.json。 比如一个单页项目, 不适合做响应式, 需要包含电脑端和移动端两个页面。可以定义为空, 则忽略掉这个情况。具体请看默认的初始化项目中的模版项目。

    部署非webpack的公共静态资源

    公共静态资源存放在resource/bundle文件夹中, js资源放在resource/js

    运行npm run deploy-static部署后, 会按照config.staticFileConcatOrder, 在js文件夹内查找到, 合并压缩至resource/bundle, 并把所有bundle资源分发到config.deployEnvType定义的所有文件夹。 运行npm run watch 时, 会自动把bundle复制到config.developEnvType对应的文件夹, 无需手动运行npm run deploy-static

    合并的 js 资源将会在所有编译后的页面的html中插入引用。

    项目风格

    项目部署配置

    通过papa.config.js配置文件, 可自定义各项部署功能, 比如可定义部署的环境, 输出路径, 让生产代码是否兼容ie8, 或改写webpack配置。详见项目配置

    自动识别小项目及页面入口

    避开了 webpack 的单项目的特性, 只需按照简单的约定规则新建一个页面目录, 即自动识别为一个 webpack 编译的入口。

    如上文定义如何识别项目所介绍, 一个目录含有proj.json就识别为一个多页项目, 否则假如符合projContainsOneOf的范围的话, 则识别为一个单页项目。

    proj.json文件只作为标记,内容可为空。

    多页项目里, 程序将寻找所有符合entryInclude的识别为页面;单页项目假如含有commSingleProjSubPage定义的子页面的话, 则自动识别为拥有子页面, 参考html风格

    html风格

    每个页面的html文件只需包含业务代码, 编译后会将内容传入html模版。 每个页面都包含一个config.json文件, 用于定义html模版的变量, 如:

      |-foo
      |---config.json
      |---index.js
      |---index.html

    假如定义了commSingleProjSubPage, 而且项目中含有这些子页面, 则json文件放在子页面文件夹的同级, 假如该值是 ['m','pc'], 则如下:

      |-foo
      |---config.json
      |---m
      |-----index.js
      |-----index.html
      |---pc
      |-----index.js
      |-----index.html

    默认的, 用npm run create命令创建的模版项目是以上第二个的目录结构。

    config.json有如下示例:

    属性 默认值 描述
    title 标题 html的<title/>
    htmlFile index.html 指定html文件的名字
    templateName_xx index_xx.handlebars 指定html模版文件。xx 是假如此页面包含 commSingleProjSubPage定义的子页面, xx就是该子页面名字。
    templateName_comm index_comm.handlebars 假如该页面不包含commSingleProjSubPage的子页面, 则使用这个来指定模版
    bodyProp "" <body/>的属性 比如"class=\"top\" data-version=\"3.0.0\""
    moreMeta "" <head/>内添加内容。如"<link rel=\"dns-prefetch\" href=\"https://www.github.com\">"

    模版文件位于resource/html

    如果项目目录不包含 config.json, 将不会使用html模版, 而会把目录顶层的index.html视为完整的 html 文件(webpack 编译出来的资源会自动填入)

    组件

    每个小项目互相独立, 但可以共用模块。两种实现方式:

    1. 共用组件

    所有小项目都可以 require 共用组件。因为是独立编译, 项目之间不会互相影响, 组件更新后, 各个项目需重新编译才会生效。这可避免在更新组件后, 因项目数量庞大, 意外地应用在不应生效的其他项目而导致意外的错误, 从而降低更新代码的负担。

    1. 公共代码包

    所有小项目都会引用共代码包, 此包有修改, 所有已在线上的项目都能获取到更新的公共包, 无需重新编译。详见部署非webpack的公共静态资源

    业务环境切换

    可在编译时在项目的业务代码里设置、切换不同的内容, 让开发过程更为灵活。比如可应用于部署环境的切换及fetch数据的环境切换;

    本地开发环境

    本地开发采用 webpack-dev-server, 默认开启了热更新功能, 并且整合了更灵活的代理功能。

    代理功能可将本地开发打通其他项目环境, 比如可共用cookie等缓存。 可以正则匹配路径。

    在一些场景中, 比如我们这个项目并非一个完全独立的站点, 它还需要与其他项目联动, 那么代理功能就非常实用了。我们可以通过papa.config.jsproxy 设置代理, 可以通过正则匹配路径实现代理, 并可以设置多个匹配规则。 如以下配置, 代理了路径以非 "activity" 开头的所有请求 到本地的80端口:

    proxy:[
          {
            filterPathname: /^\/(?!activity\/)/, 
            target: 'http://localhost:80',
          },
        ],

    集成功能

    webpack-papa-script 基于webpack, 已集成所有常见资源的处理, 以下是集成功能的列表:

    • ES6 -> ES5

    • React

    • 集成babel-runtime, Promise随便用

    • 可开启ie8兼容, 把代码转为ES3

      resource/html/index_pc.handlebars模版里, 加了ie8以下 es5-slim和 sham 文件的引用, 我们可以按照实际场景把该引用链接更换。 该文件在resource/bundle/中已预置, 执行

      npm run deploy-static

      即可把es5-slim-sham文件复制到部署目录中。

    • handlebar

    • sass-postcss-autoprofixer

    • webpack-dev-server 本地开发集成热更新及代理

    • extract-text-webpack-plugin build时独立出css文件

    编译支持的文件格式

    • js[x]
    • [s]css
    • png|jpg|gif|svg
    • handlebars|tmpl
    • woff|woff2|eot|ttf
    • pdf

    编译支持的特殊文件

    • sw.js

      使用 file-loader 编译, require后就会把该文件独立释出到输出目录;输出文件名带hash值, 可确保sw更新被触发。

    • manifest.json

      同样使用 file-loader 编译, 但不带hash值, 便于固定写在html模版。

    • *.iso.(png|gif)

      绝对不合并到css文件。其他的小于 4KB 的图片将转为 base64 合并入css文件

    以下内容因有不理想的效果, 所以没有支持:

    • 图片压缩功能

      转换png时, 现有的图片压缩插件是把png24转为png8, 会导致图片低质量, 所以在找到更好的压缩功能后再添加该功能。

    • .html文件内的资源引用

      如index.html假如有<img src="foo.jpg"/>, foo.jpg无法解析。这类功能请转移到css、React 或 handlebars实现。

    eject

    假如 webpack-papa-script 满足不了项目的需要, 随时可运行 create-webpack-papa eject, 把 webpack-papa-script 的代码转移到项目目录上, 对构建代码自行修改。不过需要注意的是, 该操作无法逆转, 操作前请确认清楚。

    项目配置

    以下是默认配置, 我们可以在项目的 papa.config.js 修改这些属性:

    {
        // 自动上传ftp需要的配置信息
        ftp: {
          host: '192.168.1.1',
          port: '',
          user: 'user',
          password: 'ps'
        },
     
        // ftp的根目录
        remoteBasePath: '',
        
        // ftp的目录
        remotePath: '/activity/{$target}/',
     
        // 需要上传到ftp的根目录
        localAssetPath: 'build/activity',
     
        // 部署上线时的host
        domainName: 'http://m.okpapa.com',
     
        // js,css,image 等资源的host
        cdnDomain: 'https://images.okpapa.com',
        
        // 代理信息, 数据类型: object array 
        proxy:[
          {
            filterPathname: /^\/(?!activity\/)/,  // 代理 pathname 以非 activity开头的所有请求
            target: 'http://localhost:80',
          },
        ],
        
        //本地开发环境的服务端口
        servePort: 3005,
        
        // 本地开发环境的静态资源基目录(同 devServer.contentBase)
        serveContentBase:'./build/',
        
        // `resource/js` 中的js文件的合并顺序, 合并生成脱离webpack的公共代码包 
        staticFileConcatOrder: [],
     
        // 合并js的命名
        staticFileName:'common.js',
     
        // 脱离webpack的公共文件的输出子路径
        staticFileSubPath:'static',
     
        // 是否启用自带的plugin
        defPlugin:{
          sri: true,      //webpack-subresource-integrity, 非https的话,请设为false
          uglifyJs: true  //是否压缩js
        },
     
        // 加入其他 webpack 插件
        customPlugin:{
          production: [], // 正式环境
          development: [] // 开发环境
        },
     
        /**
         * 即将执行编译前的时候,根据这个函数返回决定是继续还是中断。可为空,空则忽略。分正式环境和开发环境
         * aTargets {array}    用户输入所有项目的完整路径
         * return   {boolean}  false 则中断编译
         */
        shouldCompileProceed: {
          production: (aTargets)=>{return true},
          development: (aTargets)=>{return true},
        },
     
        // 覆盖预置的webpack配置
        webpackConfig: {},
     
        // 是否支持ie8
        kiss_ie8: true,
     
        // 定义一个页面下面还分哪些版本页面。
        // 比如一个单页项目, 不适合做响应式, 需要包含电脑端和移动端两个页面。可以定义为空, 则忽略掉这个情况
        commSingleProjSubPage:['m', 'pc'],
     
        // 辨别一个项目时, 只要一个文件夹里面包含以下文件或文件夹, 则认定它为一个项目。(无论单独页面还是多页面)
        projContainsOneOf: ['m', 'pc', 'proj.json', 'config.json'],
     
        // 获取所有项目时, 排除以下这些文件夹里面的内容(不会在已识别为proj的文件夹里再查找)
        projScanExclude:['modules', 'module', 'static', 'components', 'component', 'img', 'js'],
     
        // 验证 webpack 入口必须包含这个值的所有文件。
        entryInclude: ['index.js', 'index.html'],
     
        //本地开发环境的命名和前端代码注入的环境变量名。
        developEnvType: {
          deploy: 'test', //命名
          fetch: 'test'   //环境变量名
        },
        
        //正式上线的环境
        productEnvType: {
          deploy: 'pro',
          fetch: 'produce'
        },
     
        //环境名称对应的输出路径
        deployEnvType: {
          pre: 'dist/pre',
          pro: 'dist/pro',
          test: 'build/activity'
        },
     
        //环境名称对应的前端环境变量名
        deployEnvMapFetch: {
          pre: 'pre',
          pro: 'produce',
          test: 'test'
        },
     
        // 环境名称的中文名, 用于命令行的显示
        releaseEnvDesc: {
          pre: '预发环境😛',
          pro: '生产环境😝',
          test: '开发环境🤔'
        },
     
        // 前端环境的中文名
        fetchEnvDesc: {
          pre: '预发环境🥑',
          test: '测试环境🥝',
          produce: '生产环境🍓'
        },
        // 前端代码注入内容
        // mode: 前端环境变量
        // debug: 环境与productEnvType一致时, 则为false, 否则true
        frontendConfCode:`try{
          Object.assign(window.publicConfig, {
            mode:"{$mode}",
            debug:{$debug}
          });
        }catch(e){}`,
      },

    Install

    npm i webpack-papa-script

    DownloadsWeekly Downloads

    0

    Version

    3.3.5

    License

    MIT

    Unpacked Size

    89 kB

    Total Files

    32

    Last publish

    Collaborators

    • nonjene