Webpack-前端工程化之动态导入文件

9/8/2020 webpack

最近在工作中遇到一个问题. 动态导入文件

那我们怎么做到这一点呢, 我的想法是通过webpack来实现

因为以前在做vue项目的时候遇到过这个情况, 如下所示:

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

上面这段代码的作用就是把同级目录modules下的js文件全部取到, 然后通过自带的keys()方法遍历自动导入这些js文件


上面代码中, 我们的主角就是 require.context

require.context是Webpack中用来管理依赖的一个函数,此方法会生成一个上下文模块,包含目录下所有模块的引用,通过正则表达式匹配,然后require进来

 require.context('.', false, /\.vue$/)

此方法有三个参数, 参数一:要查询的目录,上述代码指的是当前目录 参数二: 是否要查询子孙目录,方法默认的值为false 参数三:要匹配的文件的后缀,是一个正则表达式,上述我要查询的是.vue文件

require.context模块返回一个函数,这个函数可以接收一个参数

导出的方法有 3 个属性: resolve, keys, id。 resolve 是一个函数,它返回请求被解析后得到的模块 id。 keys 也是一个函数,它返回一个数组,由所有可能被上下文模块处理的请求组成。 id 是上下文模块里面所包含的模块 id. 它可能在你使用 module.hot.accept 的时候被用到


# 实现

目录结构:

|modules
|—common
|——common.js
|—file
|——file.js
|—scan
|——scan.js
|bridge.js
|index.js
|package.json

modules/scan/scan.js文件:

import bridge from "../../bridge.js";

export default {
  scan: params => {
    return new Promise((resolve, reject) => {
      bridge.callHandler("scan", [params], function (res) {
        if (res.code == 1) {
          resolve(res.data);
        } else {
          reject(res.message);
        }
      });
    });
  }
};

index.js文件:

const modulesFiles = require.context('./modules', true, /\.js$/)

const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  const value = modulesFiles(modulePath).default
  // 合并所有modules文件夹下的js export default {...}
  modules = Object.assign({}, modules, value); 
  return modules
}, {})

export default window.xhyBridge = modules;

package.json文件:

{
  "name": "bridge-demo",
  "version": "1.0.0",
  "description": "for bridge",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack index.js -o dist/xhyBridge.js"
  },
  "author": "zs",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

最后通过命令把index.js打包到dist/xhyBridge.js

npm start

"how are you " " ̶s̶a̶d̶,̶ ̶b̶r̶o̶k̶e̶n̶,̶ ̶d̶e̶f̶e̶a̶t̶e̶d̶,̶ ̶c̶r̶u̶s̶h̶e̶d̶,̶ ̶l̶o̶n̶e̶l̶y̶,̶ ̶f̶a̶l̶l̶i̶n̶g̶ ̶a̶p̶a̶r̶t̶ i'm fine. "