使用内联脚本和样式将 Angular 应用程序构建为单个 HTML 文件

Q.u*_*ion 7 bundling-and-minification webpack angular

我需要将我的 Angular 应用程序构建为具有内联脚本和样式的单个 HTML 文件。默认情况下,Angular 会构建几个 js 文件和一个 css 文件,并通过 src 属性将它们添加到我的 index.html 中。

我发现了一个名为的插件html-webpack-inline-source-plugin,但它没有做任何事情。(可能是因为角度?)

有谁知道使用 webpack 将角度应用程序构建到单个文件中的另一种方法,或者是否有另一个包可以这样做?我已经做了一些研究,但没有找到解决方案。

先感谢您!

编辑:

我尝试使用以下自定义 webpack 配置,但它不会更改输出。

自定义-webpack.config.js

var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');

module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            inlineSource: '.(js|css)$'
        }),
        new HtmlWebpackInlineSourcePlugin()
    ]
}
Run Code Online (Sandbox Code Playgroud)

Nav*_*een 0

我找不到任何解决方案,所以我不得不编写一个脚本

const args = process.argv;

// angular source
const sourceDirectory = args[2]

// directory where you want to build.
const buildDirectory = args[3]

const fs = require('fs-extra');

console.log("running build script for source directory " + sourceDirectory);

console.log("Removing existing build directory " + buildDirectory)
fs.removeSync(buildDirectory);

console.log("copying angular build files to directory " + buildDirectory)
!fs.existsSync(buildDirectory) && fs.mkdirSync(buildDirectory);

// copy all the files from source to build directory and make manipulations.
fs.copySync(sourceDirectory, buildDirectory)


// find the html file, replace script tags with inline script.
const jsdom = require("jsdom");
const {JSDOM} = jsdom;

let indexFilePath = buildDirectory + "/index.html";
const htmlSource = fs.readFileSync(indexFilePath)
const dom = new JSDOM(htmlSource.toString());

const scriptTags = Array.from(dom.window.document.getElementsByTagName("script"))
const filesToRemove = []
scriptTags.map((e) => {
  let scriptFile = buildDirectory + "/" + e.getAttribute("src");
  if (scriptFile) {
    filesToRemove.push(scriptFile)
    const source = fs.readFileSync(scriptFile)
    e.removeAttribute("src")
    e.removeAttribute("type")
    e.setAttribute("type", "text/javascript")
    e.innerHTML = source.toString()
  }
})


const styleTags = Array.from(dom.window.document.getElementsByTagName("link"))
const isUrl = string => {
  try {
    return Boolean(new URL(string));
  } catch (e) {
    return false;
  }
}

styleTags.map((e) => {
  const rel = e.getAttribute("rel")
  const href = e.getAttribute("href")
  const media = e.getAttribute("media")
  if (rel === "stylesheet" && !isUrl(href) && media === "print") {
    // Remove the stylesheet
    e.parentElement.removeChild(e)
    let styleFile = buildDirectory + "/" + href;
    console.log("inlining css file " + styleFile)
    // Add the stylesheet to dom as inline.
    const style = dom.window.document.createElement("style")
    style.innerHTML = fs.readFileSync(styleFile).toString()
    dom.window.document.body.appendChild(style)
    filesToRemove.push(styleFile)
  }

})


console.log("going to remove inlined script and style files")

filesToRemove.map((file) => {
  console.log("removing " + file)
  fs.removeSync(file);
})

// rewrite index.html.
fs.writeFileSync(indexFilePath, dom.serialize())





Run Code Online (Sandbox Code Playgroud)

并将其添加到 package.json 像这样

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --output-hashing=none",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "package": "node build-scripts/index.js dist/{{YOUR_ANGULAR_PROJECT_NAME}}/  dist-inline/",
    "bundle": "yarn build && yarn package"
  },
Run Code Online (Sandbox Code Playgroud)

然后打电话yarn bundle