【问题标题】:can javascript be inline with webpack?javascript可以与webpack内联吗?
【发布时间】:2016-01-23 09:14:18
【问题描述】:

我需要在我的项目中导入一个库,该库应该是一个javascript文件,需要内联到html。

例如:

库代码:

(function(){
   var a = 0;
})();

我需要将此代码内联到 html 中。

html:

<html>
  <head>
    <script>
      (function(){
         var a = 0;
      })();
    </script>
  </head>

  <body>
  </body>
</html>

我可以用 webpack 实现吗? 我找到script-loader,但它运行脚本,而不是使其内联。

【问题讨论】:

  • 请问具体原因为什么要添加到html文件而不是webpack创建的js bundle中。?
  • @sandeep 这是一个响应式页面解决方案,它根据移动设备的大小设置html指令的字体大小。它需要在页面呈现之前执行。
  • 这应该使用 CSS @media,而不是 JS。但是如果在解析&lt;body&gt;之前有想要运行的JS,可以在&lt;head&gt;中添加&lt;script&gt;标签。

标签: javascript webpack


【解决方案1】:

我已经开始为html webpack 开发一个plugin 来支持这一点。您指定正则表达式来匹配您想要内联嵌入的文件。

plugins: [
    new HtmlWebpackPlugin({
        inlineSource: '.(js|css)$' // embed all javascript and css inline
    }),
    new HtmlWebpackInlineSourcePlugin()
] 

【讨论】:

    【解决方案2】:

    inline-source的帮助下,我毫不费力地做到了:

    1. 安装 inline-source-cli:npm install inline-source-cli
    2. inline 属性添加到您的html 文件中的脚本标记:&lt;script inline src="path/to/index.js"&gt;&lt;/script&gt;
    3. 运行inline-source --root ./dist dist/path/to/index-pre.html &gt; dist/path/to/index.html

    【讨论】:

    • 虽然只使用 webpack 会更干净一些
    【解决方案3】:

    最后,我们通过结合 webpack 和 gulp 来解决这个问题。 (有两个插件:gulp-html-replace 和 gulp-inline-source。)

    html:

     <html>
      <head>
        <!-- build:js -->
        <!-- endbuild -->
      </head>
    
      <body>
      </body>
    </html>
    

    gulpfile:

      gulp.task('replace-and-inline', function () {
          return gulp.src('./dist/index.html')
            .pipe(htmlreplace({
              'js': {
                src: [your libs which you want to be inline],
                tpl: '<script src="%s" inline></script>'
              }
            }))
            .pipe(inlinesource())
            .pipe(gulp.dest('./dist/'));
        });
    

    在 package.json 中定义一个任务,该任务将使用 webpack 编译项目,然后将 js 文件作为内联注入。

    "build": "rimraf dist && webpack --progress --hide-modules --config build/webpack.prod.conf.js;gulp replace-and-inline"
    

    当你想发布你的项目时,只需运行npm run build


    2018 年 7 月 20 日更新

    我们制作了一个 webpack 插件来解决这个问题。

    https://github.com/QuellingBlade/html-webpack-inline-plugin

    【讨论】:

    • 嗨,你的插件还能用吗?我试过但没有工作
    • 您好,我使用了您的插件,但它在 webpack5 和 html-webpack-plugin 5.5 中不起作用。
    【解决方案4】:

    对于 webpack 4,我尝试了以下 3 个插件,但没有成功

    1. html-webpack-inline-plugin
    2. html-webpack-inline-source-plugin
    3. script-ext-html-webpack-plugin

    然后我找到了这个react-dev-utils/InlineChunkHtmlPlugin,所以借用它并修改以适应我的需要:

    // use it like this
                ...
                new HtmlWebpackPlugin(...),
                new MiniCssExtractPlugin(...),
                new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/[.]js$/, /[.]css$/]),
                ...
    
    // modify InlineChunkHtmlPlugin to inline both script and style
    class InlineChunkHtmlPlugin {
        constructor(htmlWebpackPlugin, tests) {
            this.htmlWebpackPlugin = htmlWebpackPlugin;
            this.tests = tests;
        }
    
        isScript(tag) {
            return tag.tagName === 'script' && tag.attributes && tag.attributes.src;
        }
    
        isCss(tag) {
            return tag.tagName === 'link' && tag.attributes && tag.attributes.href && tag.attributes.rel === "stylesheet";
        }
    
        getInlinedTag(publicPath, assets, tag) {
            //debugger;
            const isScript = this.isScript(tag);
            const isCss = this.isCss(tag);
            if (!isScript && !isCss) {
                return tag;
            }
    
            const href = isScript ? tag.attributes.src : tag.attributes.href;
    
            const scriptName = publicPath
                ? href.replace(publicPath, '')
                : href;
            if (!this.tests.some(test => scriptName.match(test))) {
                return tag;
            }
            const asset = assets[scriptName];
            if (asset == null) {
                return tag;
            }
            return { tagName: isScript ? 'script' : 'style', innerHTML: asset.source(), closeTag: true };
        }
    
        apply(compiler) {
            let publicPath = compiler.options.output.publicPath || '';
            if (publicPath && !publicPath.endsWith('/')) {
                publicPath += '/';
            }
    
            compiler.hooks.compilation.tap('InlineChunkHtmlPlugin', compilation => {
                const tagFunction = tag =>
                    this.getInlinedTag(publicPath, compilation.assets, tag);
    
                const hooks = this.htmlWebpackPlugin.getHooks(compilation);
                hooks.alterAssetTagGroups.tap('InlineChunkHtmlPlugin', assets => {
                    assets.headTags = assets.headTags.map(tagFunction);
                    assets.bodyTags = assets.bodyTags.map(tagFunction);
                });
    
                // Still emit the runtime chunk for users who do not use our generated
                // index.html file.
                // hooks.afterEmit.tap('InlineChunkHtmlPlugin', () => {
                //   Object.keys(compilation.assets).forEach(assetName => {
                //     if (this.tests.some(test => assetName.match(test))) {
                //       delete compilation.assets[assetName];
                //     }
                //   });
                // });
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-25
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 2012-03-03
      • 2010-09-16
      • 1970-01-01
      相关资源
      最近更新 更多