23

I need to import a library to my project, the library should is a javascript file, which need to be inlined to html.

for example:

library code:

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

I need to make this code inline in html.

html:

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

  <body>
  </body>
</html>

can I implement this with webpack? I find script-loader, but it run the script, not make it inline.

4
  • Can I ask the specific reason why you want to add it to html file rather than js bundle created by webpack.? Commented Jan 23, 2016 at 13:02
  • @sandeep it is a responsive page solution which set the font-size of html directive according to the mobile device's size. it need to be executed before the page is rendered. Commented Jan 25, 2016 at 1:37
  • That should be done with CSS @media, not with JS. But if there is JS you want to run before the <body> is parsed, add the <script> tag to the <head> instead. Commented Aug 9, 2016 at 9:14
  • This question is similar to: Inline JavaScript and CSS with webpack. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Jul 9, 2024 at 2:43

4 Answers 4

25

I've started working on a plugin for html webpack to support this. You specify regex to match files that you want to embed inline.

plugins: [
    new HtmlWebpackPlugin({
        inlineSource: '.(js|css)$' // embed all javascript and css inline
    }),
    new HtmlWebpackInlineSourcePlugin()
] 
Sign up to request clarification or add additional context in comments.

Comments

8

I did it without gulp, with the help of inline-source:

  1. Install inline-source-cli: npm install inline-source-cli
  2. Add an inline attribute to the script tag in your html file: <script inline src="path/to/index.js"></script>
  3. Run inline-source --root ./dist dist/path/to/index-pre.html > dist/path/to/index.html

1 Comment

a bit cleaner to stick to just webpack though
7

At last, we solve this problem by combining webpack and gulp. (with two plugins: gulp-html-replace and 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/'));
    });

In package.json, define a task, which will compile the project using webpack and then inject the js file as inline.

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

When you want to release your project, just run npm run build


update on July.20 2018

we have made a webpack plugin to solve this issue.

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

2 Comments

Hi, does your plugin still works? I tried but not working
Hello ,I use your plugin, but it dont work in webpack5 and html-webpack-plugin 5.5.
0

for webpack 4, I tried the following 3 plugins but no luck

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

then I found this react-dev-utils/InlineChunkHtmlPlugin so borrow it and modify to fit my needs:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.