zoukankan      html  css  js  c++  java
  • webpack4 + ejs 构建多页应用

    目录结构

    ├─build   webpack配置目录
    │   ├─plugins.js
    │   ├─rules.js
    │   ├─transfromAssets.js  //简单的一个插件,处理路径问题
    │   └─webpack.config.js
    └─src
        ├─components  ejs公用组件目录
        ├─css
        ├─js
        ├─index.ejs 模板文件
        └─about.ejs
    

    源码地址:github

    使用ejs模板

    1. 安装 ejs-loader、html-loader
    2. 在 src根节点创建ejs文件,作为html的模板
    3. 使用html-webpack-plugin引入ejs模板

    index.ejs 需要向header.ejs传入htmlWebpackPlugin,否则html-webpack-plugin配置的title可能会不起作用

    <%= require('./components/header.ejs')({path:'index',htmlWebpackPlugin}) %>
    <div id="root">
      内容
    </div>
    <%= require('./components/footer.ejs')() %>
    

    header.ejs

    <head>
      <meta charset="utf-8">
      <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    

    webpack plugins,因为是多个页面,所以通过for循环插入HtmlWebpackPlugin

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const plugins = [];
    ...
    nav.forEach(value => {
      plugins.push(
        new HtmlWebpackPlugin({
          filename: `${value.path}.html`,
          template: path.resolve(__dirname, '../src', `${value.path}.ejs`),
          inject: true,
          chunks: ['common', value.path],
          favicon: './src/assets/img/favicon.ico',
          title: 'title',
          minify: {
            collapseWhitespace: true
          }
        })
      )
    })
    ...
    

    处理css

    1. 使用了less,所以需要安装loader:css-loader、less-loader
    2. 添加浏览器前缀,兼容不同版本浏览器,需要安装postcss-loader、autoprefixer
    3. 需要压缩生成的css文件,安装插件:optimize-css-assets-webpack-plugin、cssnano
    4. 将css分离成css文件,安装mini-css-extract-plugin

    处理js

    安装下babel-loader、@babel/core、@babel/preset-env,处理es6的语法。

    webpack配置

    plugins.js

    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const optimizeCss = require('optimize-css-assets-webpack-plugin');
    const TransfromAssets = require('./transfromAssets');
    const path = require('path');
    const nav = require(`../src/data.js`).nav;
    const plugins = [];
    
    nav.forEach(value => {
      plugins.push(
        new HtmlWebpackPlugin({
          filename: `${value.path}.html`,
          template: path.resolve(__dirname, '../src', `${value.path}.ejs`),
          inject: true,
          chunks: ['common', value.path],
          favicon: './src/assets/img/favicon.ico',
          title: 'title',
          minify: {
            collapseWhitespace: true
          }
        })
      )
    })
    const otherPlugins = [
      new MiniCssExtractPlugin({
        filename: '[name].[hash:8].css',
        chunkFilename: '[id].css',
      }),
      new optimizeCss({
        assetNameRegExp: /.css$/g,
        cssProcessor: require('cssnano'),
        cssProcessorOptions: {
          discardComments: {
            removeAll: true
          }
        },
        canPrint: true
      }),
      new TransfromAssets()
    ];
    plugins.splice(nav.length, 0, ...otherPlugins);
    module.exports = plugins;
    

    rules.js

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = [{
        test: /.(c|le)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: "postcss-loader",
            options: {
              plugins: [
                require("autoprefixer")
              ]
            }
          },
          'less-loader'
        ]
      },
      {
        test: /.js$/, //js文件加载器
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /.html$/,
        use: [{
          loader: 'html-loader',
          options: {
            interpolate: true,
            minimize: false
          }
        }]
      }, {
        test: /.ejs/,
        use: ['ejs-loader'],
      }
    ]
    

    transfromAssets.js 一个插件,作用:

    1. 将common.js删掉(common.js引入了公用的css,css有用但js无用所以就删啦)
    2. 将js、css存放至单独的目录,并将html里路径指向正确的路径
    function TransfromAssets(options) {};//也可以是一个类
    TransfromAssets.prototype.apply = function(compiler) {
      compiler.plugin('emit', function(compilation, callback) {
        for (var filename in compilation.assets) {
          if (/common.*js$/.test(filename)) {
            delete compilation.assets[filename];
            continue;
          }
          if (/.*[js|css]$/.test(filename)) {
            let type = /.*js$/.test(filename) ? 'js' : 'css';
            let source = compilation.assets[filename].source();
            let size = compilation.assets[filename].size();
            compilation.assets[`${type}/${filename}`] = {
              source: () => source,
              size: () => size
            }
            delete compilation.assets[filename];
          }
          if (/html$/.test(filename)) {
            let source = compilation.assets[filename].source();
            source = source.replace(/<script.*?</script>/ig, value => ~value.indexOf('common') ? '' : value);
            source = source.replace(/href="S+?.css"/ig, value => value.slice(0, 6) + 'css/' + value.slice(6));
            source = source.replace(/src=".*?.js"/ig, value => value.slice(0, 5) + 'js/' + value.slice(5));
            compilation.assets[filename].source = () => source;
          }
        }
        callback();
      })
    };
    module.exports = TransfromAssets;
    

    webpack.config.js

    const path = require('path');
    const plugins = require('./plugins');
    const rules = require('./rules');
    
    module.exports = {
      entry: {
        common: '@src/js/common.js',
        index: '@src/js/index.js',
        detail: '@src/js/list.js',
      },
      output: {
        path: path.resolve(__dirname, '../dist/'),
        filename: "[name].[hash:8].js"
      },
      devServer: {
        inline: true,
        historyApiFallback: true,
      },
      resolve: {
        alias: {
          '@': path.join(__dirname, '..'),
          '@src': path.join(__dirname, '..', 'src')
        }
      },
      module: {
        rules
      },
      plugins
    }
    
  • 相关阅读:
    代理信息[Python] 实现网络爬虫
    线程希望IOS开发(67)之简单的线程方法
    生产环境紧急修改表存储引擎:MyISAM 为 InnoDB步骤
    Mysql优化SQL语句的一般步骤
    window 2003 实现多用户远程登录
    XSS的知识普及和预防办法
    免积分下载CSDN软件和新浪资料
    mysql开启慢查询方法
    在线JS/CSS/HTML压缩
    我们项目中需要准备的技术
  • 原文地址:https://www.cnblogs.com/hl1223/p/11003316.html
Copyright © 2011-2022 走看看