Skip to content

feflow/feflow-devkit-ivweb

Repository files navigation

feflow-devkit-ivweb

GitHub license npm package NPM downloads PRs Welcome developing with feflow

feflow 套件, 适用于NOW直播业务和活动类型的项目构建

特性

  • 使用webpack4 + babel7 最新的构建解决方案
  • 对H5开发友好,默认集成 Rem 方案,解决适配问题
  • 支持多页面打包的开发方式
  • 支持less和typescript的文件打包
  • 支持CSS Modules

安装

确保feflow的版本在 v0.12.0 以上, 可以通过如下命令安装最新feflow版本

$ npm install @feflow/cli -g

快速使用

添加.feflowrc.js配置文件

在项目根目录添加 .feflowrc.js 配置文件

{module.exports = {
    devkit: {
        commands: {
            dev: {
                builder: "feflow-devkit-ivweb:dev",
                options: {
                    product: "",
                    outDir: "dist",
                    moduleName: "my",
                    bizName: "project",
                    minifyHTML: true,
                    minifyCSS: true,
                    minifyJS: true,
                    inlineCSS: true,
                    usePx2rem: true,
                    remUnit: 37.5,
                    remPrecision: 6,
                    inject: true,
                    useTreeShaking: true,
                    port: 8001,
                    hot: true,
                    cdn: "",
                    domain: "",
                    externals: [
                        {
                            module: "react",
                            entry: "//now8.gtimg.com/now/lib/17.0.1/react.js",
                            global: "React",
                        },
                        {
                            module: "react-dom",
                            entry: "//now8.gtimg.com/now/lib/17.0.1/react-dom.js",
                            global: "ReactDOM",
                        },
                    ],
                    webpackConfig: {
                        smartStrategyOption: {
                            plugins: "append",
                        },
                        config: {
                            plugins: [],
                        },
                    },
                },
            },
            build: {
                builder: "feflow-devkit-ivweb:build",
                options: {
                    product: "",
                    outDir: "dist",
                    moduleName: "my",
                    bizName: "project",
                    minifyHTML: true,
                    minifyCSS: true,
                    minifyJS: true,
                    inlineCSS: true,
                    usePx2rem: true,
                    remUnit: 37.5,
                    remPrecision: 6,
                    inject: true,
                    useTreeShaking: true,
                    port: 8001,
                    hot: true,
                    cdn: "",
                    domain: "",
                    externals: [
                        {
                            module: "react",
                            entry: "//now8.gtimg.com/now/lib/17.0.1/react.js",
                            global: "React",
                        },
                        {
                            module: "react-dom",
                            entry: "//now8.gtimg.com/now/lib/17.0.1/react-dom.js",
                            global: "ReactDOM",
                        },
                    ],
                    webpackConfig: {
                        smartStrategyOption: {
                            plugins: "append",
                        },
                        config: {
                            plugins: [],
                        },
                    },
                },
            },
        },
    },
};

命令

$ fef dev      # 本地开发时的命令
$ fef build    # 发布时的打包命令, 打出的包在工程的public目录, 包含 cdn, webserver 和 offline 三个文件夹

文档

内联

同时支持Fis3项目的inline语法糖写法和ejs的写法

  • 内联 html:
<!--inline[/assets/inline/meta.html]-->
  • 内联 javascript
<script src="@tencent/report-whitelist?__inline"></script>

备注:如果希望内联某个 JS 文件,需要使用相对路径的写法。

代理设置

  • 执行 feflow dev 命令后会在本地的 8001 端口开启一个 WDS 服务,所有的静态资源(html, css, js, img) 都会在内存里面。可以通过 http://127.0.0.1:8001/webpack-dev-server 查看

  • Fiddler配置把之前的本地绝对路径改成 本地server 路径即可:

热更新支持

  • 如果要支持热更新,需要再增加一条代理_webpack_hmr的配置,如:

/^https?://now\.qq\.com/(__webpack_hmr)$/ http://127.0.0.1:8001/$1

  • 在项目中,用react-hot-loaderpageComponent变为可接受热更新的组件
import { hot } from 'react-hot-loader'
class pageComponent extends Component {
    ...
}
export default hot(module)(pageComponent)

使用CSS Modules

本构建器默认启用CSS Modules,可生成全局唯一的类名/id名,避免样式污染。只需将样式文件命名为[name].module.(css|less),那么定义在里面的类名和id就会经过CSS Modules转化,不按此规则命名的样式文件,其内容不会经过CSS Modules处理。推荐结合babel-plugin-react-css-modules使用,可简化语法,在项目中安装配置

npm i -S babel-plugin-react-css-modules postcss-less

然后在项目根目录下添加一个babel.config.js文件,内容如下:

const path = require('path');
const loaderUtils = require('loader-utils');

/**
 * 用于css-loader转换类名,与构建器内置的一致:
 * 1.去除样式文件名的'.module'前缀;
 * 2.遇到以'index.module.xxx'命名的样式文件使用文件夹名代替文件名来组成转换后的类名。
 * 此方法基于'react-dev-utils/getCSSModuleLocalIdent',增加less正则匹配(https://www.npmjs.com/package/react-dev-utils)
 * @param context webpack传给css-loader的context对象
 * @param localIdentName css-loader的options.localIdentName,没传默认是'[hash:base64]',这里用不到
 * @param localName 原始css类名
 * @param options css-loader中三个配置项的组合,长这样:
   {
      regExp: options.localIdentRegExp,
      hashPrefix: options.hashPrefix || '',
      context: options.context,
   }
 */
function getCSSModulesLocalIdent(
    context,
    localIdentName,
    localName,
    options
) {
    // Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style
    const fileNameOrFolder = context.resourcePath.match(
        /index\.module\.(css|scss|sass|less)$/
    )
        ? '[folder]'
        : '[name]';
    // Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
    const hash = loaderUtils.getHashDigest(
        path.posix.relative(context.rootContext, context.resourcePath) + localName,
        'md5',
        'base64',
        5
    );
    // Use loaderUtils to find the file or folder name
    const className = loaderUtils.interpolateName(
        context,
        fileNameOrFolder + '_' + localName + '__' + hash,
        options
    );

    // remove the .module that appears in every classname when based on the file.
    return className.replace('.module_', '_');
}

/**
 * 由于入参不一致,这里包装一层调用getCSSModulesLocalIdent
 * @param name 原始类名
 * @param filename 样式文件路径
 */
function generateScopedName(name, filename) {
    const loaderContext = {
        rootContext: process.cwd(), // 保持与webpack loader context的rootContext一致(默认是项目根目录)
        resourcePath: filename
    };
    return getCSSModulesLocalIdent(
        loaderContext,
        undefined,
        name,
        {}
    );
}

module.exports = function (api) {
    api.cache(true);

  	const presets = [];
    const plugins = [
        [
            'react-css-modules',
            {
                context: process.cwd(), // 保持与webpack loader context的rootContext一致(默认是项目根目录)
                filetypes: {
                    '.less': {
                        syntax: 'postcss-less'
                    }
                },
                generateScopedName,
                webpackHotModuleReloading: true,
              	autoResolveMultipleImports: true
            }
        ]
    ];

    return {
      	presets,
        plugins
    };
};

然后启动项目,那么在[name].module.(css|less)中定义的类名就可以在React组件中通过styleName prop引用。

如果你同时需要使用feflow.json的babelrcPath配置,那么请同样以js的形式定义babel配置,并把上述内容整合进去,然后再指定给babelrcPath(因为指定了babelrcPath就不能同时读取根目录的babel.confis.js)。

相关资料:

测试

  1. git clone这个用于烟雾测试的模板项目
  2. 配置.travis.yml,可以参考模板项目README
  3. Travis-ci中打开此项目的自动构建

版本日志

版本日志

许可证

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published