在完整堆栈中通过 nodejs 模块编译 Web 资产的最佳实践 php/js Web 应用程序

best practice for compiling web assets via nodejs modules in a full stack php/js web app

我正在寻找一种方法来将我的网络资产编译到一个完整的堆栈网络应用程序中。例如,假设我们的网络应用程序中使用了以下框架、库和模块:

这是现代网络应用程序的典型或更好的传统设置。我正在努力如何或使用哪些模块能够顺利地将我的所有资产编译到我的构建目标中。在我的例子中,它是一个 public 可访问的网络文件夹,我的所有资产都捆绑在该文件夹中。 需要编译以下内容:

最主要的事情就到此为止了。但 Bower 实际上并不关心我们如何将这些库编译到单个文件中以及我们如何将字体 and/or 图像复制到我们的构建目标。 我已经看过 grunt、bower 和 Yeoman。最后一个似乎是一个很好的工具来包装我需要的东西。

此时任何帮助、提示或使用经验都将非常有用。我认为这是许多开发人员的常见问题,但尚未得到解答。我在互联网上搜索了几个小时。因此,欢迎任何帮助。

我现在正在使用 Node JS、Grunt 和 bootstrap-sass。因此,我们还有其他资产,这些资产不会被编译并抛出我的任务。所以我添加了一个同步任务。它只复制两个路径之间修改过的文件。这对我来说非常有用,但我不确定它是否是最佳实践:

/**
 * My Gruntfile.
 *
 */
module.exports = function (grunt)
{
    grunt.loadNpmTasks("grunt-sass");
    grunt.loadNpmTasks("grunt-sass-lint");
    grunt.loadNpmTasks("grunt-bootlint");
    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-postcss");
    grunt.loadNpmTasks("grunt-sync");

    var relaxerrors = [
        "App/Mvc/views/notallowed.phtml",
        "App/Mvc/views/ajax/*.phtml",
        "App/Mvc/views/event/*.phtml",
        "App/Mvc/views/forum/*.phtml",
        "App/Mvc/views/index/news.phtml",
    ];

    grunt.initConfig({
            sass: {
                options: {
                    includePaths: ["node_modules/bootstrap-sass/assets/stylesheets/bootstrap"],
                    precision: 10,
                    sourcemap: "inline",
                    trace: true,
                    unixNewlines: true
                },
                dist: {
                    files: {
                        "web/css/frontend.min.css": "assets/styles/frontend.scss",
                        "web/css/backend.min.css": "assets/styles/backend.scss",
                        "web/lib/bootstrap/css/bootstrap.min.css": "node_modules/bootstrap-sass/assets/stylesheets/bootstrap.scss"
                    }
                }
            },
            sasslint: {
                target: [ "assets/styles/*.scss" ]
            },
            jshint: {
                files: [ "assets/js/*.js" ],
                options: {
                    globals: {
                        jquery: true
                    }
                }
            },
            bootlint: {
                options: {
                    stoponerror: true,
                    showallerrors: true,
                    stoponwarning: false,
                    relaxerror: {
                        "E001": relaxerrors,
                        "W001": relaxerrors,
                        "W002": relaxerrors,
                        "W003": relaxerrors,
                        "W005": relaxerrors
                    }
                },
                files: [ "App/Mvc/views/*.phtml", "App/Mvc/views/*.html" ]
            },
            postcss: {
                options: {
                    map: true,
                    processors: [
                        require("pixrem")(), // add fallbacks for rem units
                        require("autoprefixer")({
                            browsers: ["last 2 versions"]
                        })
                    ]
                },
                dist: {
                    src: ["web/lib/bootstrap/css/*.css", "web/css/*.css"]
                }
            },
            sync: {
                main: {
                files: [{
                    src: [
                      "node_modules/bootstrap-sass/assets/fonts/**", // include everything
                      '!**/*.txt' // but exclude txt files
                    ],
                    dest: 'web/lib/bootstrap/fonts',
                }],
                pretend: true, // Don't do any IO. Before you run the task with `updateAndDelete` PLEASE MAKE SURE it doesn't remove too much.
                verbose: true // Display log messages when copying files
                }
            }
        }
    );

    grunt.registerTask("validate:styles", [ "sasslint" ]);
    grunt.registerTask("validate:js", [ "jshint" ]);
    grunt.registerTask("validate:bootstrap", [ "bootlint" ]);
    grunt.registerTask("validate:all", [ "validate:bootstrap", "validate:styles", "validate:js" ]);
    grunt.registerTask("build:styles", [ "validate:styles", "sass", "postcss", "sync" ]);

    // default task. Run all
    grunt.registerTask("default", [ "validate:all", "sass", "postcss", "sync" ]);
};

和我的 package.json:

{
  "name": "myProjectDeps",
  "version": "1.0.0",
  "dependencies": {
    "grunt": "^1.0.1",
    "grunt-bootlint": "^0.10.1",
    "grunt-cli": "^1.2.0",
    "grunt-contrib-compress": "^1.3.0",
    "grunt-contrib-concat": "^1.0.1",
    "grunt-contrib-cssmin": "^1.0.2",
    "grunt-contrib-jshint": "^1.0.0",
    "grunt-contrib-uglify": "^2.0.0",
    "grunt-sass-lint": "^0.2.0",
    "grunt-sync": "^0.6.2"
  },
  "devDependencies": {
    "autoprefixer": "^6.5.1",
    "bootstrap-sass": "^3.3.7",
    "grunt-postcss": "^0.8.0",
    "grunt-sass": "^1.2.1",
    "node-sass": "^3.10.1",
    "pixrem": "^3.0.2",
    "typescript": "^2.0.6",
    "typings": "^1.5.0"
  }
}

如果这对您不起作用,请全局安装 grunt 或在 node_modules 中调用相对于项目根目录的 grunt 文件,例如。 g.

my/dir/root> ./node_modules/bin/grunt valdiate:styles

(未测试是否有效)