美文网首页webpack学习Vue.js 资料前端工程
Webpack工程化解决方案easywebpack

Webpack工程化解决方案easywebpack

作者: hubcarl | 来源:发表于2017-10-26 12:23 被阅读388次

    1.概要

    随着越来越多的项目采用 Vue, React, Weex 进行业务开发, 在前端构建方面大多数是用webpack进行构建。但存在以下问题:

    各个项目都是自己从零编写 Webpack 配置,存在很多定制性的配置,无法复用,大多都是复制拷贝。
    Webpack 配置项多,繁杂,社区插件有非常多,往往不知道哪个到底可以用,存在什么问题,需要各自摸索。当需要满足开发环境,正式环境,js/css/image压缩,css extract, css module, sass, less, stylus, postcss, babel, cdn,单页面,多页面,热更新, 前端渲染,服务器渲染等特性时,配置非常复杂。在这种情况下,急需一套稳定的 Webpack 配置骨架,简化项目使用难度和维护成本。

    最近半年来,基于 Webpack(Vue,Weex) 经过实际项目的不断迭代和大家的建议,在前端渲染,单页面渲染,服务端渲染等方面都进行过实际项目的实践,在此基础上面沉淀出一套建基于 Webpack 通用基础配置且可扩展性强的前端工程化解决方案 easywebpack。

    2.easywebpack功能介绍

    easywebpack 是在 Webpack 上扩展出来的前端项目构建工程化解决方案, 同时支持 Vue,React 服务端端渲染构建,也支持 Weex Nativ 和 Web 构建. 同时内置 Webpack 常用功能和基础插件,支持插件动态安装,功能开启,框架扩展等特性。

    目前 easywebpack 已支持 Webpack3(easywebpack 3.x.x) 和 Webpack2(easywebpack 1.x.x),很多新特性可以马上尝鲜了。另外支持 Mac 和 Window 系统(被 Windows 坑了好久,如果可以,尽可能用 Mac)。

    • 首先我们看看 easywebpack 具备的基础功能:
    easywebpack.png
    • 基于 easywebpack 实现的解决方案
    webpack-project.png

    2.1 基础功能

    • 支持服务端渲染, 前端渲染, 静态页面渲染三种构建方式
    • 支持单页面, 多页面服务端渲染构建模式
    • 默认支持 dev,test, prod 环境配置
    • 集成 webpack-hot-middleware 热更新实现
    • 支持 entry 原生配置和目录遍历自动构造 entry 功能
    • 支持自动根据后缀名构建 entry 文件,比如 .vue.jsx 文件为入口文件
    • 支持 es6 class 继承方式编写 Webpack 配置
    • 支持 js/css/image 压缩, 内置支持 CDN 特性
    • 支持 css/sass/less/stylus, 支持css module 和 css extract 特性
    • 支持 loader 是否启用,合并,覆盖配置
    • 支持 plugin 是否启用,合并,覆盖配置
    • 支持 loader 和 plugin npm module 是否启用,按需安装
    • 支持 eslint, postcss 等特性
    • 提供 easywebpack-cli 和 webpack-tool 辅助工具。

    2.2 内置loader

    • babel-loader
    • eslint-loader
    • style-loader
    • css-loader
    • postcss-loader
    • sass-loader
    • less-loader
    • stylus-loader
    • url-loader

    2.3 内置plugin

    • extract-text-webpack-plugin
    • npm-install-webpack-plugin
    • webpack.optimize.ModuleConcatenationPlugin
    • webpack.NoEmitOnErrorsPlugin
    • webpack.ProvidePlugin
    • webpack.DefinePlugin
    • webpack.optimize.CommonsChunkPlugin
    • webpack.optimize.UglifyJsPlugin
    • webpack.HotModuleReplacementPlugin
    • progress-bar-webpack-plugin
    • imagemin-webpack-plugin
    • directory-named-webpack-plugin
    • webpack.NormalModuleReplacementPlugin
    • webpack.IgnorePlugin
    • html-webpack-plugin

    3.已有解决方案

    基于 easywebpack 基础骨架,目前已扩展 Vue React Weex 三种解决方案,其中 easywebpack-vueeasywebpack-react 支持纯前端构建和Node端构建模式,easywebpack-weex 支持 Native 和 Web 构建模式。

    如果你需要基于 easywebpack 扩展其他解决方案也很简单, 只需要继承 easywebpackWebpackClientBuilder(前端渲染构建模式) 和 WebpackServerBuilder(服务端渲染构建模式) 即可, 你只需要把框架相关的扩展进来即可。 大概实现如下:

    4.解决方案扩展实现

    4.1 前端渲染构建模式

    const EasyWebpack = require('easywebpack');
    class WebpackClientBuilder extends EasyWebpack.WebpackClientBuilder {
    constructor(config) {
    super(config);
    // call below api custom client builder
    }
    }
    module.exports = WebpackClientBuilder;
    

    4.2 服务端渲染构建模式

    const EasyWebpack = require('easywebpack');
    class WebpackServerBuilder extends EasyWebpack.WebpackServerBuilder {
    constructor(config) {
    super(config);
    // call below api custom server builder
    }
    }
    module.exports = WebpackServerBuilder;
    

    具体实现请参考 easyebpack-vue`,`easyebpack-react, easyebpack-weex

    5.命令行工具

    5.1 easywebpack-cli 命令行工具

    • Vue, React, Weex 骨架项目初始化工具, 支持纯前端项目和Egg项目
    • 提供命令行 easywebpackeasy 命令编译项目和启动静态功能
    • 依赖 webpack-tool 工具构建

    5.1.1 特性

    5.1.2 安装

    $ npm i easywebpack-cli -g
    

    5.1.3 运行

    easywebapck -h
    

    Usage: easywebpack [command] [options]
    Options:

    -V, --version output the version number
    -f, --filename [path] webpack config file name, default webpack.config.js
    -w, --watch webpack watch and hot-update
    -m, --hash webpack md5 hash js/css/image
    -c, --compress webpack compress js/css/image
    -b, --build [option] w(watch), m(hash) , c(compress), ex: wm/wc/mc/wmc
    -h, --help output usage information

    Commands:

    init [options] init webpack config or boilerplate for Vue/React/Weex
    install npm install
    print [env] [options] print webpack config, support print by env or config node key
    build [env] webpack building
    server [env] webpack building and start server

    5.1.4. 命令介绍

    1. 配置模板和Boilerplate初始化
    • easywebpack init

    step one:

    cli-init-step-one.png

    step two:

    cli-init-step-two.png
    2. 编译举例
    • easywebpack build
    • easywebpack build -f build/webpack.config.js
    • easywebpack build -c
    • easywebpack build dev
    • easywebpack build test
    • easywebpack build prod
    • easywebpack build -b wmc

    默认读取项目根目录下的 webpack.config.js 配置

    3. 编译和启动服务举例
    • easywebpack server
    • easywebpack server -f build/webpack.config.js
    • easywebpack server dev
    • easywebpack server test
    • easywebpack server prod
    • easywebpack server -b wmc

    默认读取项目根目录下的 webpack.config.js 配置

    4. 打印配置
    easywebpack print -h
    

    Usage: print [env] [options]
    print webpack config, support print by env or config node key

    Options:
    -n, --node [key] print webpack config info by config node key, example: [module/module.rules/plugins] and so on
    -h, --help output usage information

    • easywebpack print -n module
    • easywebpack print dev -n entry
    • easywebpack print test -n module.rules
    • easywebpack print prod -n module.rules[0]
    • easywebpack print -n plugins
    • easywebpack print -n plugins[0]
    • easywebpack print -n output
    • easywebpack print -n resolve

    默认读取项目根目录下的 webpack.config.js 配置
    GitHub:https://github.com/hubcarl/easywebpack-cli

    5.2 webpack-tool 命令行工具

    webpack-tool 是一个纯粹的 Webpack 构建工具, 不依赖任何框架, 支持以下特性:

    • 提供 Webpack 配置编译功能
    • 提供 Webpack 编译结果文件UI视图导航和访问功能
    使用
    //build/index.js
    const WebpackTool = require('webpack-tool');
    const weexNativeConfig = require('./weex/native');
    const weexWebConfig = require('./weex/web');
    const NODE_ENV = process.env.VIEW;
    const webpackConfig = [weexNativeConfig, weexWebConfig];
    const webpackTool = new WebpackTool();
    if (NODE_ENV === 'development') {
      // start webpack build and show build result ui view
      webpackTool.server(webpackConfig);
    } else {
      webpackTool.build(webpackConfig);
    }
    
    build-navigation.png

    6.项目构建方案配置案例

    6.1 纯前端项目配置和构建

    假如要实现基于 Vue 或者 React 实现一个纯前端渲染项目改如何配置 webpack.config.js.

    6.1.1 项目结果要求如下:

    project.png
    • 支持单页面和多页面entry配置
    • 支持根据 .vue 或者 .react 构建入口文件
    • 支持根据目录遍历, 项目page根目录为 page
    • 支持热更新,支持css extract, 支持 css和sass(默认支持),支持构建预览
    • 支持cdn配置,支持构建完成回调用于编写自定义逻辑
    • 支持公共文件抽取,抽取文件默认为 vendor.js
    • 支持 es6 编写
    • 支持js/css/image压缩和hash
    • 支持eslint,babel, postcss
    • 支持dev(不压缩,无hash,支持热更新)和 prod(压缩hash,css exteract) 配置

    6.1.2 基于 easywebpack-vueeasywebpack-cli

    上面的要求 easywebpack-vue 都支持,其中 支持eslint,babel, postcss 和 autoprefixer是默认开启

    • 按照上面的截图新建好项目,或者可以通过 easywebpack-ci 工具初始化完成

    • 项目安装 easywebpack-vue 解决方案依赖

      npm install easywebpack-vue --save-dev
      
    • 编写 ${project}/webpack.config.js配置

    const BUILD_ENV = process.env.BUILD_ENV;
    const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
    module.exports = {
      type: 'client, // 指定只构建前端渲染
      framework: 'vue', // 支持 react/weex
      entry: {
        include: 'page',
        exclude: ['page/test'],
        template: 'view/layout.html'
      }
      loader: {
        client: 'framework/vue/entry/client-loader.js'
      }
      alias: {
        asset: 'asset',
        component: 'component',
        framework: 'framework',
        store: 'store'
      },
      cdn,
      done(){ // 编译完成
      // 这里可以做你想做的事情哟,比如 打包上传 CDN
        if(cdn && cdn.url){
        }
      }
    }
    

    只需要配上面这么多, 就可以 Running 了,因为 easywebpack-vue 把 babel,postcss,sass都默认支持了,当然你可以扩展。

    • 命令行编译

    首先请安装 easywebpack-ci 工具, 然后就可以用 easywebpackeasy 命令
    npm install easywebpack-ci -g

    • 命令行启动运行
    easywebpack server 或 easywebpack server dev
    easywebpack server prod
    
    • 命令行编译,默认开发模式
    easywebpack build 或 easywebpack build dev
    easywebpack build prod
    
    • 获取 Webpack 配置结果
    const EasyWebpack = require('easywebpack-vue');
    const webpackConfigList = EasyWebpack.getWebpackConfig()
    

    6.1.3 基于 easywebpack-reacteasywebpack-cli

    如果要用react实现类似功能, 请把上面 framework 改为 react

    6.2 Vue/React Server Side Render 配置

    如果要基于上面的要求实现一个 Vue /React 服务端渲染的构建配置, 该如何配置,非常简单。

    6.2.1 构建配置

    • copy 一份上面的配置
    • 去掉 type:client 配置
    • 如果 react,framework配置改为 'framework: react', 另外安装 easywebpack-react 依赖
    • 添加 server loader template, 请查看配置举例。
    loader: {
      client: 'framework/vue/entry/client-loader.js',
      server: 'framework/vue/entry/server-loader.js'
    }
    

    完整结构如下:

    const BUILD_ENV = process.env.BUILD_ENV;
    const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
    module.exports = {
      framework: 'vue', // 支持 react/weex
      entry: {
        include: 'page',
        exclude: ['page/test'],
        template: 'view/layout.html'
      }
      loader: {
       client: 'framework/vue/entry/client-loader.js',
       server: 'framework/vue/entry/server-loader.js'
      }
      alias: {
        asset: 'asset',
        component: 'component',
        framework: 'framework',
        store: 'store'
      },
      cdn,
      done(){ // 编译完成
        // 这里可以做你想做的事情哟,比如 打包上传 CDN
        if(cdn && cdn.url){
        }
      }
    }
    

    6.2.2 结合 Vue vue-server-renderer 做服务端渲染, 核心代码如下:

    const renderer = require('vue-server-renderer');
    // filepath 为 Webpack 构建的服务端代码
    const bundleRenderer = renderer.createBundleRenderer(filepath, renderOptions);
    // data 为 Node端获取到的数据
    const context = { state: data };
    return new Promise((resolve, reject) => {
      bundleRenderer.renderToString(context, (err, html) => {
      if (err) {
        reject(err);
      } else {
        resolve(html);
      }
    });
    

    请参考 egg-view-vue 和 egg-view-vue-ssr 实现: egg-view-vueegg-view-vue-ssr

    拿到服务端渲染的 html 后,可以根据 manifest 资源依赖注入 css,js 等依赖,实际项目这里要考虑缓存。完整的基于 koa, express 项目请参考下面要介绍的 Egg + Vue 服务端渲染实现。

    6.2.3 结合 React react-dom/server 做服务端渲染, 核心代码如下:

    const React = require('react');
    const ReactDOMServer = require('react-dom/server');
    

    请参考 egg-view-react 和 egg-view-react-ssr 实现: egg-view-reactegg-view-react-ssr

    拿到服务端渲染的 html 后,可以根据 manifest 资源依赖注入 css,js 等依赖,实际项目这里要考虑缓存。完整的基于 koa, express 项目请参考下面要介绍的 Egg + React 服务端渲染实现。

    6.3 Egg + Vue 服务端渲染(Server Side Render)配置

    如果要基于上面的要求实现一个 Egg + Vue 服务端渲染的构建配置, 我们服务端渲染的配置基础上面增加 egg: true 配置即可。

    6.3.1 完整配置结构如下:

    const BUILD_ENV = process.env.BUILD_ENV;
    const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
    
    module.exports = {
      egg: true,
      framework: 'vue', // 支持 react/weex
      entry: {
        include: 'page',
        exclude: ['page/test'],
        template: 'view/layout.html'
      }
      loader: {
        client: 'framework/vue/entry/client-loader.js',
        server: 'framework/vue/entry/server-loader.js'
      }
      alias: {
        asset: 'asset',
        component: 'component',
        framework: 'framework',
        store: 'store'
      },
      cdn,
      done(){ // 编译完成
        // 这里可以做你想做的事情哟,比如 打包上传 CDN
        if(cdn && cdn.url){
        }
      }
    }
    

    6.3.2 安装相关配置插件

    项目骨架: egg-vue-webpack-boilerplate

    6.4 Egg + React 服务端渲染(Server Side Render)配置

    如果要基于上面的要求实现一个 Egg + React 服务端渲染的构建配置,我们服务端渲染的配置基础上面增加 egg: true即可。

    完整结构如下:

    const BUILD_ENV = process.env.BUILD_ENV;
    const cdn = BUILD_ENV === 'prod' ? { url: 'http://your.cdn.com'} : '',
    module.exports = {
      egg: true,
      framework: 'react', // 支持 react/weex
      entry: {
      include: 'page',
      exclude: ['page/test'],
      template: 'view/layout.html',
      loader: {
        client: 'framework/vue/entry/client-loader.js',
        server: 'framework/vue/entry/server-loader.js'
      },
      alias: {
        asset: 'asset',
        component: 'component',
        framework: 'framework',
        store: 'store'
      },
      cdn,
      done(){ // 编译完成
        // 这里可以做你想做的事情哟,比如 打包上传 CDN
        if(cdn && cdn.url){
        }
      }
    }
    

    骨架项目请见: egg-react-webpack-boilerplate

    6.5 Weex Native 和 Web 双端模式构建

    假如要实现基于 Weex + Vue 构建配置项目该如何配置 webpack.config.js. 除了上面的要求外,还需要支持 Native 和 Web 构建。 基于 easywbpack-weex 配置也非常简单, 只需要 把 framework 配置为 weex 即可。

    • 首先安装 easywbpack-weex
    npm i easywbpack-weex --save-dev
    
    • webpack.config.js 配置如下:
    module.exports = {
      egg: true,
      framework: 'weex',
      entry: {
        include: 'page',
        exclude: ['page/test'],
        template: 'view/layout.html'
      } 
      alias: {
        asset: 'asset',
        component: 'component',
        framework: 'framework',
        store: 'store'
      },
      done(){ // 编译完成
       // 这里可以做你想做的事情哟
      }
    }
    
    • 获取 Webpack Config 配置
    const EasyWebpack = require('easywebpack-weex');
    const webpackConfigList = EasyWebpack.getWebpackConfig()
    
    • 开发运行
    easy server dev
    easy server test
    easy server prod
    
    • 编译
    easy build dev
    easy build test
    easy build prod
    

    骨架项目请见: easywebpack-weex-boilerplate

    相关文章

      网友评论

      本文标题:Webpack工程化解决方案easywebpack

      本文链接:https://www.haomeiwen.com/subject/foahpxtx.html