background

Recently, the company wants to create a shortcut entrance for the functions in app, which is similar to the bus code in Alipay and added to the desktop. For now, just do ios.

Investigate how Alipay does this, in fact, using Safari’s PWA function, encoded web content and ICONS to save to the desktop. Click the desktop shortcut to open the webpage to execute JS and jump to the corresponding function of the App. pwa

Open to

Safari opens a list of urls that contain the encoding of the page’s content. And using base64 bits of code, will solve the second open invalid bug.

Because you want to package out a base64 bit code, you need to inline it into a file. So webpack is going to start on its own

1. Put up the Webpack shelf first
mkdir pwa && cd pwa
npm init -y
npm install webpack webpack-cli --save-dev
Copy the code
2. Write a static HTML page

Because I want to use HtmlWebpackPlugin this plug-in to transform, and set up multiple languages

Let’s start with Head

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta content="yes" name="apple-touch-fullscreen"< span style = "max-width: 100%"yes" name="apple-mobile-web-app-capable"<meta content="black" name="apple-mobile-web-app-status-bar-style"< span style = "box-sizing: border-box! Important"viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,minimal-ui"> // view <title> your title</title> <link sizes="114x114" rel="apple-touch-icon-precomposed"
    href="Your image URL icon"> / / save to the desktop icon < script > / / set rem document. The documentElement. Style.css. FontSize = 100 * document. The documentElement. ClientWidth / 375 +"px"</script> <! <style> </style> </head>Copy the code

In the body, htmlWebpackPlugin. Options. Lang is used to set up multi-language

<body>
  <div id="B_container" class="backguide" style="display:none">
    <div class="tips"> < %if (htmlWebpackPlugin.options.lang === 'zh-Hans') {%> You are about to enter <%}else if (htmlWebpackPlugin.options.lang === 'en') {%>
        You are about to enter
      <% } %>
    </div>
    <button class="enter" onclick="jumpSchema()"</button> </div> <div id="app" style="display:none">
    <div class="title"> < %if (htmlWebpackPlugin.options.lang === 'zh-Hans') {%> Add service to desktop <%}else if (htmlWebpackPlugin.options.lang === 'en') {%>
        Add services to the desktop
      <% } %>
    </div>
  </div>
  <script>
    window.MTSchema = 'Link to the app you want to jump to';

    function jumpSchema() {
      window.location.href = window.MTSchema;
    }

    function getIOSversion() {
      if(/iP(hone|od|ad)/.test(navigator.platform)) { var e = navigator.appVersion.match(/OS (\d+)_(\d+)_? (\d+)? /);return [parseInt(e[1], 10), parseInt(e[2], 10), parseInt(e[3] || 0, 10)]
      }
    }
    if(window. The navigator. Standalone) {/ / by the window. The navigator. Standalone detection Safari Web application is open full-screen var v = getIOSversion ();if(13 <= v[0]) {// the system above 13 will not automatically jump to enter the page document.getelementById ("B_container").style.display = "flex"
      } else {
        document.getElementById("app").style.display = "flex"
      }
      window.location.href = window.MTSchema;
    } else {
      document.getElementById("app").style.display = "flex"
    }
  </script>
</body>
Copy the code
3. The webpack configuration

Since urL-loader’s conversion of HTML files to Base64 was performed before HtmlWebpackPlugin, injecting CSS script is invalid. After the plan to write a script conversion

const path = require("path");
const merge = require("webpack-merge");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
const LANG = process.env.LANG;
const NODE_ENV = process.env.NODE_ENV;

let baseConfig = {
  entry: "./src/main.js",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "dist")
  },
  devServer: {
    contentBase: false,
    compress: true,
    hot: true,
    host: "0.0.0.0", port: 9000}, module: {rules: [{// Use inline directly because converting to JS files is too bigtest: /\.scss$/,
        use: [
          "style-loader"// Generate the JS string as a style node"css-loader"// Convert CSS to CommonJS modules"sass-loader"// To compile Sass into CSS, use Node Sass]}]} by default, plugins: New HtmlWebpackPlugin({template:) {// new HtmlWebpackPlugin({template:); // New HtmlWebpackPlugin({template:);"./src/index.html",
      filename: "index.html",
      inject: false// collapse language minify: {collapseWhitespace:true// Delete whitespace, newline}, // Here is the code that was intended to inject but caused the file to be too large // inlineSource:'.(js|css)$'/ / dependence HtmlWebpackInlineSourcePlugin}), / / new HtmlWebpackInlineSourcePlugin ()]};if (NODE_ENV === "development") {
  baseConfig = merge(baseConfig, {
    plugins: [new webpack.HotModuleReplacementPlugin()]
  });
}
module.exports = baseConfig;

Copy the code
4.package.json

Set up multiple languages and run scripts

"scripts": {
    "build": "rm -rf ./dist && cross-env LANG=zh-Hans NODE_ENV=production webpack --env.lang=zh-Hans && node ./src/toBase64.js"."build:en": "rm -rf ./dist && cross-env LANG=en NODE_ENV=production webpack --env.lang=en && node ./src/toBase64.js"."dev": "cross-env LANG=en NODE_ENV=development webpack-dev-server --hot"
}
Copy the code
5.toBase64.js

Convert to Base64-bit

const fs = require('fs');
const path = require('path');
const mineType = require('mime-types');
 
let filePath = path.resolve('./dist/index.html');
 
let data = fs.readFileSync(filePath);
data = new Buffer(data).toString('base64');
 
let base64 = 'data:' + mineType.lookup(filePath) + '; base64,' + data;
 
fs.writeFileSync(path.resolve('./dist/index.html'), base64);
Copy the code

conclusion

It feels really imperfect, but of course this is only a working version and will need to be optimized later. Oneself small rookie one, have a problem hope everybody points out, grow up together.