How to use html templates in electron framework?

2020-03-26 06:45发布

问题:

I need to build a cross platform app with multiple windows. So I would like to know how to use html templates in electron.

回答1:

Based on a similar question and what I've seen, there's no built in html template language in Electron, which is actually great because it allows you to use any other template language.

I'm currently playing with ejs in Electron. Below is my index.ejs template file:

<html lang="en">
<head>
  <title>The Index Page</title>
</head>
<body>
  <h1>Welcome, this is the Index page.</h1>
  <% if (user) { %>
    <h3>Hello there <%= user.name %></h3>
  <% } %>
</body>
</html>

And below is a section of my main.js file where the above template is rendered and loaded onto the BrowserWindow. Note that I've left out most of the boilerplate code:

const ejs = require('ejs');
//... Other code
let win = new BrowserWindow({width: 800, height: 600});
//... Other code
// send the data and options to the ejs template
let data = {user: {name: "Jeff"}};
let options = {root: __dirname};
ejs.renderFile('index.ejs', data, options, function (err, str) {
  if (err) {
    console.log(err);
  }
  // Load the rendered HTML to the BrowserWindow.
  win.loadURL('data:text/html;charset=utf-8,' + encodeURI(str));
});

I'll give some credit to this gist for helping me find the data:text/html;charset=utf-8 part of the url that can be used to load dynamic content.

UPDATE

I'm actually not using this anymore. It's faster to just load the default html and use the native DOM methods. The Electron Quickstart program shows how to do this nicely.



回答2:

Another option is to do the templating during your build. Here is a simple example using gulp to add nonces to the CSP meta tag and the inline script.

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-<%= scriptNonce %>';">
    <title>Basic Electron App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="application/javascript" nonce=<%= scriptNonce %>>
      require('./index.js');
    </script>
  </body>
</html>

and in gulfile.js add the following to what you already have and make sure this task is included in your pipeline. You can also just update your current html task with the code below.

const template = require('gulp-template');
const uuidv4 = require('uuid/v4');

gulp.task('copy-html', () => {
  // Create nonces during the build and pass them to the template for use with inline scripts and styles
  const nonceData = {
    scriptNonce: new Buffer(uuidv4()).toString('base64'),
    styleNonce: new Buffer(uuidv4()).toString('base64')
  };
  return gulp.src('src/*.html')
  .pipe(template(nonceData))
  .pipe(gulp.dest('dist/'));
});

This is a very stripped down example. I have a more complete example at https://github.com/NFabrizio/data-entry-electron-app if anyone is interested, though there is still one warning when running the application because one of the packages I am using pulls in react-beautiful-dnd, which adds inline styles but does not currently accept nonces.



标签: electron