{"id":19318312,"url":"https://github.com/feflow/builder-webpack4","last_synced_at":"2025-04-22T17:31:01.305Z","repository":{"id":54959859,"uuid":"152042000","full_name":"feflow/builder-webpack4","owner":"feflow","description":"腾讯IVWEB团队使用的基于Webpack4的业务开发构建器","archived":false,"fork":false,"pushed_at":"2021-01-19T16:21:49.000Z","size":168,"stargazers_count":67,"open_issues_count":7,"forks_count":19,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-12T11:08:37.596Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/feflow.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-08T08:08:32.000Z","updated_at":"2022-07-06T16:21:30.000Z","dependencies_parsed_at":"2022-08-14T07:30:35.548Z","dependency_job_id":null,"html_url":"https://github.com/feflow/builder-webpack4","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feflow%2Fbuilder-webpack4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feflow%2Fbuilder-webpack4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feflow%2Fbuilder-webpack4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feflow%2Fbuilder-webpack4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/feflow","download_url":"https://codeload.github.com/feflow/builder-webpack4/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250141424,"owners_count":21381599,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T01:18:06.956Z","updated_at":"2025-04-22T17:31:00.905Z","avatar_url":"https://github.com/feflow.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# builder-webpack\n\n[![](https://img.shields.io/travis/feflow/builder-webpack4.svg)](https://travis-ci.com/feflow/builder-webpack4)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/iv-web/feflow/blob/master/LICENSE)\n[![npm package](https://img.shields.io/npm/v/builder-webpack4.svg?style=flat-square)](https://www.npmjs.org/package/builder-webpack4)\n[![NPM downloads](http://img.shields.io/npm/dt/builder-webpack4.svg?style=flat-square)](https://npmjs.org/package/builder-webpack4)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/cpselvis/builder-webpack4/pulls)\n[![developing with feflow](https://img.shields.io/badge/developing%20with-feflow-1b95e0.svg)](https://github.com/feflow/feflow)\n\nWebpack 构建器, 适用于NOW直播业务和活动类型的项目构建\n\n## 特性\n\n- 使用webpack4 + babel7 最新的构建解决方案\n- 对H5开发友好，默认集成 Rem 方案，解决适配问题\n- 支持多页面打包的开发方式\n- 支持less和typescript的文件打包\n- 支持CSS Modules\n\n## 安装\n\n确保feflow的版本在 v0.12.0 以上, 可以通过如下命令安装最新feflow版本\n```\n$ npm install feflow-cli -g\n```\n\n## 快速使用\n\n### 添加feflow.json配置文件\n\n在项目根目录添加 `feflow.json` 配置文件\n\n``` sh\n{\n    \"builderType\": \"builder-webpack3\",\n    \"builderOptions\": {\n        \"product\": \"now\",                                    // 产品，此处可以是 now 或者 shangfen\n        \"domain\": \"now.qq.com\",                              // 域名，离线包的域名需要使用\n        \"cdn\": \"11.url.cn\",                                  // 资源发布到的cdn名称\n        \"moduleName\": \"mobile\",                              // 部署的模块\n        \"bizName\": \"category\",                               // 业务名称\n        \"minifyHTML\": true,                                  // 是否压缩 html\n        \"minifyCSS\": true,                                   // 是否压缩 js\n        \"minifyJS\": true,                                    // 是否压缩 css\n        \"inlineCSS\": true,                                   // 生成的 css 是否内联到首屏\n        \"usePx2rem\": true,                                   // 是否使用 Rem\n        \"useReact\": true,                                    // 是否是 React，如果为false，则不会在 html 中引用 React 框架 \n        \"remUnit\": 37.5,                                     // Rem 单位，对于 375 视觉稿，此处填写 37.5，750视觉稿需要改成 75 \n        \"remPrecision\": 8,                                   // Rem 的精度，即 px 转换成了 rem 后的小数点后位数\n        \"inject\": true,                                      // 打包生成的 js 文件是否自动注入到 html 文件 body 之后\n        \"port\": 8001,                                        // 本地开发的 webpack 构建服务进程端口号\n        \"babelrcPath\": \"\"                                    // 指定.babelrc文件相对根目录的路径，默认加载根目录的.babelrc\n        \"externals\": [                                       // 基础框架不打入到 bundle 里面\n            {\n                \"module\": \"react\",\n                \"entry\": \"//11.url.cn/now/lib/16.2.0/react.min.js?_bid=3123\",\n                \"global\": \"React\"\n            },\n            {\n                \"module\": \"react-dom\",\n                \"entry\": \"//11.url.cn/now/lib/16.2.0/react-dom.min.js?_bid=3123\",\n                \"global\": \"ReactDOM\"\n            }\n        ]\n    }\n}\n```\n\n### 命令\n\n```sh\n$ feflow dev      # 本地开发时的命令\n$ feflow build    # 发布时的打包命令, 打出的包在工程的public目录, 包含 cdn, webserver 和 offline 三个文件夹\n```\n\n## 文档\n\n### 内联\n\n同时支持Fis3项目的inline语法糖写法和ejs的写法\n\n- 内联 html:\n\n``` sh\n\u003c!--inline[/assets/inline/meta.html]--\u003e\n```\n\n- 内联 javascript\n\n``` sh\n\u003cscript src=\"@tencent/report-whitelist?__inline\"\u003e\u003c/script\u003e\n```\n\n备注：如果希望内联某个 JS 文件，需要使用相对路径的写法。\n\n### 代理设置\n\n- 执行 `feflow dev` 命令后会在本地的 8001 端口开启一个 WDS 服务，所有的静态资源(html, css, js, img) 都会在内存里面。可以通过 http://127.0.0.1:8001/webpack-dev-server  查看\n\n![](https://qpic.url.cn/feeds_pic/ajNVdqHZLLDpvNiayyEbzqB9V61CRiallnRdEKFaViaxw7pibicBKgEI8vw/)\n\n- Fiddler配置把之前的本地绝对路径改成 本地server 路径即可：\n\n![](https://qpic.url.cn/feeds_pic/Q3auHgzwzM72dIPZyXSdy8srwzIOTovf0VSaNlBzE98ueBiaibIVSHkA/)\n\n### 热更新支持\n\n- 如果要支持热更新，需要再增加一条代理`_webpack_hmr`的配置，如：\n\n`/^https?://now\\.qq\\.com/(__webpack_hmr)$/ http://127.0.0.1:8001/$1`\n\n- 在项目中，用`react-hot-loader`将`pageComponent`变为可接受热更新的组件\n\n```js\nimport { hot } from 'react-hot-loader'\nclass pageComponent extends Component {\n    ...\n}\nexport default hot(module)(pageComponent)\n```\n\n### 使用CSS Modules\n\n本构建器默认启用CSS Modules，可生成全局唯一的类名/id名，避免样式污染。只需将样式文件命名为[name].module.(css|less)，那么定义在里面的类名和id就会经过CSS Modules转化，不按此规则命名的样式文件，其内容不会经过CSS Modules处理。推荐结合babel-plugin-react-css-modules使用，可简化语法，在项目中**安装配置**：\n\n```shell\nnpm i -S babel-plugin-react-css-modules postcss-less\n```\n\n然后在项目根目录下添加一个babel.config.js文件，内容如下：\n\n```javascript\nconst path = require('path');\nconst loaderUtils = require('loader-utils');\n\n/**\n * 用于css-loader转换类名，与构建器内置的一致：\n * 1.去除样式文件名的'.module'前缀；\n * 2.遇到以'index.module.xxx'命名的样式文件使用文件夹名代替文件名来组成转换后的类名。\n * 此方法基于'react-dev-utils/getCSSModuleLocalIdent'，增加less正则匹配（https://www.npmjs.com/package/react-dev-utils）\n * @param context webpack传给css-loader的context对象\n * @param localIdentName css-loader的options.localIdentName，没传默认是'[hash:base64]'，这里用不到\n * @param localName 原始css类名\n * @param options css-loader中三个配置项的组合，长这样：\n   {\n      regExp: options.localIdentRegExp,\n      hashPrefix: options.hashPrefix || '',\n      context: options.context,\n   }\n */\nfunction getCSSModulesLocalIdent(\n    context,\n    localIdentName,\n    localName,\n    options\n) {\n    // Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style\n    const fileNameOrFolder = context.resourcePath.match(\n        /index\\.module\\.(css|scss|sass|less)$/\n    )\n        ? '[folder]'\n        : '[name]';\n    // Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.\n    const hash = loaderUtils.getHashDigest(\n        path.posix.relative(context.rootContext, context.resourcePath) + localName,\n        'md5',\n        'base64',\n        5\n    );\n    // Use loaderUtils to find the file or folder name\n    const className = loaderUtils.interpolateName(\n        context,\n        fileNameOrFolder + '_' + localName + '__' + hash,\n        options\n    );\n\n    // remove the .module that appears in every classname when based on the file.\n    return className.replace('.module_', '_');\n}\n\n/**\n * 由于入参不一致，这里包装一层调用getCSSModulesLocalIdent\n * @param name 原始类名\n * @param filename 样式文件路径\n */\nfunction generateScopedName(name, filename) {\n    const loaderContext = {\n        rootContext: process.cwd(), // 保持与webpack loader context的rootContext一致（默认是项目根目录）\n        resourcePath: filename\n    };\n    return getCSSModulesLocalIdent(\n        loaderContext,\n        undefined,\n        name,\n        {}\n    );\n}\n\nmodule.exports = function (api) {\n    api.cache(true);\n\n  \tconst presets = [];\n    const plugins = [\n        [\n            'react-css-modules',\n            {\n                context: process.cwd(), // 保持与webpack loader context的rootContext一致（默认是项目根目录）\n                filetypes: {\n                    '.less': {\n                        syntax: 'postcss-less'\n                    }\n                },\n                generateScopedName,\n                webpackHotModuleReloading: true,\n              \tautoResolveMultipleImports: true\n            }\n        ]\n    ];\n\n    return {\n      \tpresets，\n        plugins\n    };\n};\n\n```\n\n然后启动项目，那么在[name].module.(css|less)中定义的类名就可以在React组件中通过`styleName` prop引用。\n\n\u003e 如果你同时需要使用feflow.json的`babelrcPath`配置，那么请同样以js的形式定义babel配置，并把上述内容整合进去，然后再指定给`babelrcPath`（因为指定了`babelrcPath`就不能同时读取根目录的babel.confis.js）。\n\n相关资料：\n\n* CSS Modules官网：https://github.com/css-modules/css-modules\n* babel-plugin-react-css-modules：https://github.com/gajus/babel-plugin-react-css-modules\n* **[荐]**关于CSS Modules用法的详细介绍（内网）：[http://km.oa.com/group/29185/articles/show/382256#3.%20CSS%20Modules%E4%BD%BF%E7%94%A8%E7%BB%8F%E9%AA%8C](http://km.oa.com/group/29185/articles/show/382256#3. CSS Modules使用经验)\n* **[荐]**收集了CSS Modules + babel-plugin-react-css-modules常用示例的仓库（内网）：https://git.code.oa.com/alexqxxu/CSS-Modules-Demo \n\n### 测试\n\n1. `git clone`这个用于烟雾测试的[模板项目](https://github.com/feflow/generator-smoking-test)\n2. 配置`.travis.yml`，可以参考模板项目[README](https://github.com/feflow/generator-smoking-test)\n3. 在[Travis-ci](https://travis-ci.org/feflow/builder-webpack3)中打开此项目的自动构建\n\n## 版本日志\n\n[版本日志](CHANGELOG.md)\n\n## 许可证\n\n[MIT](https://tldrlegal.com/license/mit-license)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeflow%2Fbuilder-webpack4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeflow%2Fbuilder-webpack4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeflow%2Fbuilder-webpack4/lists"}