简体   繁体   English

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

[英]Resolving dynamic module with Webpack and Laravel Mix

Good time of the day,一天中的好时光,

Recently I've been trying to implement dynamic module loading functionality for my project.最近我一直在尝试为我的项目实现动态模块加载功能。 However, I'm failing for past few hours.但是,过去几个小时我都失败了。 To give you an idea of what I'm trying to achieve, here is the structure of the project为了让您了解我想要实现的目标,这是项目的结构

  • plugins插件
    • developer开发商
      • assets资产
        • scss scss
          • developer.scss开发者.scss
        • js js
          • developer.js开发者.js
  • themes主题
    • theme_name主题名称
      • webpack.mix.js webpack.mix.js
      • node_modules/节点模块/
      • source来源
        • js js
          • application.js应用程序.js
          • bootstrap.js引导程序.js
        • scss scss
          • application.scss应用程序.scss
          • _variables.scss _variables.scss

So, in order to get the available plugins , I've made the following function所以,为了获得可用的插件,我做了以下功能

/**
 * 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;
        });
    }
}

This function loads all the available plugins for the specified developer, then goes inside and looks for the assets folder, if it exists, then it returns it and we can work with the provided directory later.此函数为指定的开发人员加载所有可用的插件,然后进入并查找资产文件夹,如果存在,则返回它,我们稍后可以使用提供的目录。

The next step is to generate the reference for every plugin (direct path to the developer_name.js file) which later should be 'mixed' into one plugins.bundle.js file.下一步是为每个插件生成引用(developer_name.js 文件的直接路径),稍后应该将其“混合”到一个plugins.bundle.js文件中。

In order to achieve this, the following piece of code 'emerged'为了实现这一点,下面的代码“出现”

_.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;
    }
});

And the last step before I'm starting to edit the configuration of the Webpack is to get the folders for both scss and js files for all plugins and all developers:在我开始编辑 Webpack 配置之前的最后一步是为所有插件和所有开发人员获取 scss 和 js 文件的文件夹:

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

And here is where the problems start to appear.这就是问题开始出现的地方。 I've tried many solutions offered either here on GitHub (in respective repositories), but I've failed so many times.我已经尝试了在 GitHub 上(在各自的存储库中)提供的许多解决方案,但是我失败了很多次。

The only error I'm having now is this one:我现在唯一的错误是这个:

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"

Yes, i know that webpack.mix.js file should be in the root folder of the project, however, i'm just developing theme, which uses modules developed by other members of the team.是的,我知道webpack.mix.js文件应该在项目的根文件夹中,但是,我只是在开发主题,它使用团队其他成员开发的模块。
So, idea was to:所以,想法是:

  • Start build process: npm run dev|prod开始构建过程: npm run dev|prod
  • Load plugins for all needed developers automatically自动为所有需要的开发人员加载插件
  • Use methods and html tags provided by the plugin (it is a mix of PHP for API routing and Vue.js for Components, etc) as follows: <test-component></test-component>使用插件提供的方法和html标签(它是用于API路由的PHP和用于组件等的Vue.js的混合)如下: <test-component></test-component>

Any help is really appreciated, i just cant get my head around that error.任何帮助都非常感谢,我只是无法理解那个错误。 If you need extra information, i'm ready to help since i myself need help to solve this issue =)如果您需要额外的信息,我随时准备提供帮助,因为我自己需要帮助来解决这个问题 =)

Update: The latest Webpack config used by mix.webpackConfig() (still failing though)更新: 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);

And this is the content of the webpackModules variable:这是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'
]

Okay, after 7 hours I've decided to try the most obvious method to solve the problem, to create node_modules folder in the root of the project and install laravel-mix there, and it worked like a charm.好的,7 小时后我决定尝试最明显的方法来解决问题,在项目的根目录中创建node_modules文件夹并在那里安装laravel-mix ,它就像一个魅力。

Looks like, if it cant find the module in the directory outside the root scope of the Webpack, it will go up the tree to find the node_modules folder.看起来,如果在 Webpack 根范围之外的目录中找不到模块,它会向上查找node_modules文件夹。

Developers should allow us to set the root folder for Webpack to fetch all the modules i guess, but well, problem is solved anyways.开发人员应该允许我们设置 Webpack 的根文件夹以获取我猜的所有模块,但是无论如何问题都解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM