npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@wecity/static-env-config

v1.0.37

Published

## 前端静态文件配置驱动

Downloads

20

Readme

@wecity/static-env-conifg

前端静态文件配置驱动

解决问题:打包后,可以动态替换或者更改一个config.js的文件,达到驱动前端包个性化部署

支持配置

  • API 前缀 (发起请求时依赖)
  • Router 前缀 (应用运行时依赖)
  • Resource 前缀 (打包构建时强依赖)

插件参数

| 名称 | 必须 | 说明 | 类型 | 默认值 | |--| -- |--|-- |-- | | var | 否 | 挂载到window上的变量名称,如默认可在window.STATIC_ENV_CONFIG获取到配置值 | string | STATIC_ENV_CONFIG | | url | 否 | 配置文件的请求路径地址,默认没有精准到env.config.js,需要ng配置支持 | string | ./envconfig | | fileName | 否 | 生成的文件名字 | string | env.config.js | | headResourceTags | 否 | 头部资源标签 | array | [] | | bodyResourceTags | 否 | body内部资源标签 | array | [] | | configKey | 否 | 可自定义配置中config-key的名字 | object | { router: 'ROUTER_PREFIX', resource: 'RESOURCE_PREFIX', api: 'API_PREFIX' } | | config | 是 | 配置内容,其中根级下必须具备configKey配置里value三个字段,如不改动configKey默认配置时,此配置必须包含'ROUTER_PREFIX', 'RESOURCE_PREFIX', 'API_PREFIX' | object |{ ROUTER_PREFIX: '/', API_PREFIX: '/', RESOURCE_PREFIX: '/' } | | customerConfigPath | 否 | 使用qiankun接入微前端后,由于主应用与子应用的window隔离机制,配置对象无法正确挂载,所以此配置可以将配置挂载到其他地方,默认会将上述配置的var值拼接后再挂载到一份至配置上,如默认会挂载到document.head.STATIC_ENV_CONFIG | string | document | | microApp | 否 | 使用qiankun接入微前端后,子应用应在此字段配置子应用名字,对应qiankun主应用内使用registerMicroApps注册子应用的name值 | string | | | microAppRenderAlone | 否 | 配置子应用microApp后生效,控制子应用是否支持独立渲染,在未被主应用集成的情况下,通过url访问可直接渲染 | boolean | true |

使用方式(gsd-web举例)

打包文件设置

// vue.config.js
const StaticEnvConfig = require('@wecity/static-env-config').default

const configOptions = {
  // 自定义任何配置
}
// 注意需要把配置文件里面的publicPath全指定到 / 上去
// 此处默认环境变量如下
// VUE_APP_ROUTER_BASE = '/xxx'
// VUE_APP_API_BASE_URL = '/xxx'
// VUE_APP_RESOURCE_PREFIX = '/xxx'
module.exports = {
  publicPath: '/',
  // ...
  chainWebpack: config => {
    config
      .plugin('static-env-config')
      .use(
        new StaticEnvConfig({
          config: {
            ROUTER_PREFIX: process.env.VUE_APP_ROUTER_BASE,
            API_PREFIX: process.env.VUE_APP_API_BASE_URL,
            RESOURCE_PREFIX: process.env.VUE_APP_RESOURCE_PREFIX,
            ...configOptions
          }
        })
      )
  }
  // ...
  devServer: {
    publicPath: '/'
    // ...
  }
}

插件输出文件(默认env.config.js)

配置插件后,build目录下会生成一个静态js,默认名字为env.confg.js,如上图配置会生成内容如下

window.STATIC_ENV_CONFIG = {
  ROUTER_PREFIX: '/xxx',
  API_PREFIX: '/xxx',
  RESOURCE_PREFIX: '/xxx',
  ...configOptions // 展开配置内容
}

部署改动

前端代码中配置

统一配置出口

// src/core/config/index.js

const config = {
  // 环境配置
  env: {
    ...window.STATIC_ENV_CONFIG
  }
}

export default config

Router前缀

// router.js
import Router from 'vue-router'

function init(Vue) {
  Vue.use(Router)
  return new Router({
    mode: 'history',
    base:
      process.env.NODE_ENV === 'production'
        // 加载配置中的路由前缀
        ? `${Vue.prototype.$config.env.ROUTER_PREFIX}/`
        : '',
    routes: [
      // ...
    ]
  })

API前缀

// src/core/sdk/request.js
// ...
const request = axios.create({
  baseURL: window.STATIC_ENV_CONFIG.API_PREFIX,
  maxRedirects: 0
})
// ...

qiankun微前端接入指引

此时有一个名为app-vue的子应用需要接入

主应用

主应用接入插件可参照上述指引完成

// 主应用中注册
import Vue from 'vue'
const { registerMicroApps, start } = qiankun
const router = new VueRouter({
  mode: 'history',
  base: '/test'
})
Vue.use(VueRouter)
registerMicroApps([
  {
    // 注意此处name配置
    name: 'app-vue',
    entry: '//localhost:8765',
    container: '#subApp',
    activeRule: '/test/app-vue'
  }
])
start()
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

子应用接入

子应用支持维护独立的配置文件

// 子应用接入支持自身维护配置文件,需要配置config内容
module.exports = {
  publicPath: '/',
  // ...
  chainWebpack: config => {
    config
      .plugin('static-env-config')
      .use(
        new StaticEnvConfig({
          // 配置子应用名称
          microApp: 'app-vue',
          // 自定义配置挂载路径 默认值document可省略,切勿使用window,由于qiankun沙箱机制,子应用中的window使用了代理,会影响到配置加载
          customerConfigPath: 'document',
          // 自定义配置访问key 默认值STATIC_ENV_CONFIG 可省略
          var: 'STATIC_ENV_CONFIG',
          config: {
            API_PREFIX: '/',
            RESOURCE_PREFIX: '/',
            ROUTER_PREFIX: '/',
            ...// 其他自定义配置
          }
        })
      )
  }
  // ...
  devServer: {
    publicPath: '/'
    // ...
  }
}

子应用接入后,在子应用内部访问配置文件变量

// 访问方式为上述插件配置中的 var + '_' + microApp
// 其中var不填默认值为:STATIC_ENV_CONFIG
// 故上述配置下的子应用配置访问路径如下
document['STATIC_ENV_CONFIG_app-vue']
// {
//  API_PREFIX: '/',
//  RESOURCE_PREFIX: '/',
//  ROUTER_PREFIX: '/',
//  ...
//}

配置生效流程图

avatar

插件编译流程

avatar

HTML包变化

使用插件前

<!DOCTYPE html>
  <html lang=en>
  <head>
    <title>Test</title>
    <meta charset=utf-8>
    <meta http-equiv=Cache-Control content="no-cache, no-store, must-revalidate">
    <meta http-equiv=Pragma content=no-cache>
    <meta http-equiv=Expires content=0>
    <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1">
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <link rel=icon href=/ioc/snpt/static/favicon.png>
    <script src=/ioc/snpt/static/jquery-3.4.1.min.js charset=utf-8></script>
    <link href=/ioc/snpt/assets/css/chunk-5170aa6e.9fd5c425.css rel=prefetch>
    <link href=/ioc/snpt/assets/css/chunk-51e3a1cd.c4ce7aa1.css rel=prefetch>
    ....
    <link href=/ioc/snpt/assets/css/chunk-vendors.7b2a2b57.css rel=stylesheet>
    <link href=/ioc/snpt/assets/css/chunk-common.6f982596.css rel=stylesheet>
    <link href=/ioc/snpt/assets/css/index.c3acc7f2.css rel=stylesheet>
  </head>
  <body>
    <noscript><strong>We're sorry but cloud-open-admin-temp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
    <div id=app></div>
    <script src=/ioc/snpt/assets/js/chunk-vendors.88d2e607.js></script>
    <script src=/ioc/snpt/assets/js/chunk-common.13aa863b.js></script>
    <script src=/ioc/snpt/assets/js/index.9b303247.js></script>
  </body>
</html>

使用插件后

<!DOCTYPE html>
  <html lang=en>
  <head>
    <title>Test</title>
    <meta charset=utf-8>
    <meta http-equiv=Cache-Control content="no-cache, no-store, must-revalidate">
    <meta http-equiv=Pragma content=no-cache>
    <meta http-equiv=Expires content=0>
    <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1">
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <script id="static-env-config-config-script" src="./envconfig"></script>
  </head>
  <body>
    <noscript><strong>We're sorry but cloud-open-admin-temp doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
    <div id=app></div>
    <script id=static-env-config-load-script>
      var loadMap = {"head":[...], "body": [...]};
      var config = window.STATIC_ENV_CONFIG;
      var bodyScript = document.createElement('div');
      for (var key in loadMap) {
        var tagList = loadMap[key];
        (tagList || []).forEach(tag => {
          var load = document.createElement(tag.tagName);
          var attributes = tag.attributes;
          if (attributes) {
            for (var attr in attributes) {
              var value = attributes[attr];
              if (['src', 'href'].includes(attr)) value = config['RESOURCE_PREFIX'] + value;
              load.setAttribute(attr, value);
            }
          }
          if (key === 'body') { bodyScript.append(load); } else if (key === 'head') { document.head.append(load); }
        });
      }
      if (bodyScript.innerHTML) document.write(bodyScript.innerHTML);
      var script = document.getElementById('static-env-config-load-script');
      document.body.removeChild(script);
    </script>
  </body>
</html>