使用Webpack和Laravel Mix解析动态模块

时间:2018-02-18 22:10:41

标签: javascript webpack babeljs mix

一天的美好时光,

最近,我一直在尝试为我的项目实现动态模块加载功能。但是,我在过去的几个小时里都失败了。为了让您了解我想要实现的目标,这是项目的结构

  • 插件
    • 显影剂
      • 资产
        • SCSS
          • developer.scss
        • JS
          • developer.js
  • 主题
    • THEME_NAME
      • webpack.mix.js
      • node_modules /
        • JS
          • 的application.js
          • bootstrap.js
        • SCSS
          • application.scss
          • _variables.scss

所以,为了获得可用的插件,我已经做了以下功能

/**
 * Get all plugins for specified developer
 * which have 'assets' folder
 * @param developerPath
 * @param plugins
 */
function getDeveloperPlugins(developerPath, plugins) {
    if (fs.existsSync(developerPath)) {
        fs.readdirSync(developerPath).forEach(entry => {
            let pluginPath = path.resolve(developerPath, entry),
                assetsPath = path.resolve(pluginPath, 'assets');
            if (fs.existsSync(assetsPath))
                plugins[entry] = assetsPath;
        });
    }
}

此函数加载指定开发人员的所有可用插件,然后进入并查找 assets 文件夹(如果存在),然后返回它,我们可以稍后使用提供的目录。

下一步是为每个插件生成引用(developer_name.js文件的直接路径),后者应该是' mixed'到一个 plugins.bundle.js 文件中。

为了实现这一目标,下面的代码出现了'

_.forEach(plugins, (directory, plugin) => {
    let jsFolder = path.resolve(directory, 'js'),
        scssFolder = path.resolve(directory, 'scss');
    if (fs.existsSync(jsFolder)) {
        webpackModules.push(jsFolder);
        let possibleFile = path.resolve(jsFolder, plugin + '.js');
        if (fs.existsSync(possibleFile))
            pluginsBundle.js[plugin] = possibleFile;
    }
    if (fs.existsSync(scssFolder)) {
        webpackModules.push(scssFolder);
        let possibleFile = path.resolve(scssFolder, plugin + '.scss');
        if (fs.existsSync(possibleFile))
            pluginsBundle.scss[plugin] = possibleFile;
    }
});

在我开始编辑Webpack配置之前的最后一步是获取所有插件和所有开发人员的scss和js文件的文件夹:

let jsPluginsBundle = _.values(pluginsBundle.js),
    scssPluginsBundle = _.values(pluginsBundle.scss);

这就是问题开始出现的地方。我已经在GitHub(在各自的存储库中)尝试过很多解决方案,但是我已经失败了很多次。

我现在唯一的错误就是这个:

ERROR in F:/Web/Projects/TestProject/plugins/developer/testplugin/assets/js/testplugin.js
Module build failed: ReferenceError: Unknown plugin "transform-object-rest-spread" specified in "base" at 0, attempted to resolve relative to "F:\\Web\\Projects\\TestProject\\plugins\\developer\\testplugin\\assets\\js"

是的,我知道 webpack.mix.js 文件应该在项目的根文件夹中,但是,我只是在开发主题,它使用由其他成员开发的模块。团队。
所以,想法是:

  • 开始构建过程: npm run dev | prod
  • 自动为所有所需的开发人员加载插件
  • 使用插件提供的方法和html标签(它是用于API路由的PHP和用于组件的Vue.js等),如下所示:<test-component></test-component>

任何帮助都非常感谢,我无法理解这个错误。如果您需要额外的信息,我随时准备提供帮助,因为我自己需要帮助来解决这个问题=)

更新: mix.webpackConfig() 使用的最新Webpack配置(但仍然失败)

let webpackConfiguration = {
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
                loader: require.resolve('babel-loader'),
                options: {
                    presets: [
                        'babel-preset-env'
                    ].map(require.resolve),
                    plugins: [
                        'babel-plugin-transform-object-rest-spread'
                    ].map(require.resolve)
                }
            }
        }]
    },
    resolve: {
        modules: webpackModules
    }
};

mix.webpackConfig(webpackConfiguration);

这是webpackModules变量的内容:

[ 
  'F:\\Web\\Projects\\TestProject\\themes\\testtheme\\node_modules',
  'F:\\Web\\Projects\\TestProject\\themes\\testtheme',
  'F:\\Web\\Projects\\TestProject\\plugins\\developer\\testplugin\\assets\\js',
  'F:\\Web\\Projects\\TestProject\\plugins\\developer\\testplugin\\assets\\scss'
]

1 个答案:

答案 0 :(得分:1)

好的,7小时后我决定尝试最明显的方法来解决问题,在项目的根目录中创建 node_modules 文件夹并安装 laravel-mix 那里,它就像一个魅力。

看起来,如果它无法在Webpack的根范围之外的目录中找到该模块,它将在树上找到 node_modules 文件夹。

开发人员应该允许我们设置Webpack的根文件夹来获取我猜的所有模块,但是,问题总是得到解决。