目录结构

├─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
}

webpack4 + ejs 构建多页应用的更多相关文章

  1. React构建单页应用方法与实例

    React作为目前最流行的前端框架之一,其受欢迎程度不容小觑,从这门框架上我们可以学到许多其他前端框架所缺失的东西,也是其创新性所在的地方,比如虚拟DOM.JSX等.那么接下来我们就来学习一下这门框架 ...

  2. Nodejs in Visual Studio Code 12.构建单页应用Scrat实践

    1.开始 随着前端工程化深入研究,前端工程师现在碉堡了,甚至搞了个自己的前端网站http://div.io/需要邀请码才能注册,不过里面的技术确实牛.距离顶级的前端架构,目前博主应该是far away ...

  3. 通过Web Api 和 Angular.js 构建单页面的web 程序

    通过Web Api 和 Angular.js 构建单页面的web 程序 在传统的web 应用程序中,浏览器端通过向服务器端发送请求,然后服务器端根据这个请求发送HTML到浏览器,这个响应将会影响整个的 ...

  4. 用webpack4从零开始构建react脚手架

    用webpack4从零开始构建react脚手架 使用脚手架 git clone git@github.com:xiehaitao0229/react-wepack4-xht.git` `cd reac ...

  5. vue2.0 构建单页应用最佳实战

    vue2.0 构建单页应用最佳实战   前言 我们将会选择使用一些 vue 周边的库vue-cli, vue-router,vue-resource,vuex 1.使用 vue-cli 创建项目2.使 ...

  6. webpack4.0构建项目流程

    webpack4.0构建项目流程,具体的就不一一唠叨了,这里给出构建流程步骤: 流程大图: 下载高清大图

  7. 使用 Vuex + Vue.js 构建单页应用

    鉴于该篇文章阅读量大,回复的同学也挺多的,特地抽空写了一篇 vue2.0 下的 vuex 使用方法,传送门:使用 Vuex + Vue.js 构建单页应用[新篇] ------------------ ...

  8. 使用 Vuex + Vue.js 构建单页应用【新篇】

    使用 Vuex + Vue.js 构建单页应用[新篇] 在去年的七月六号的时候,发布了一篇 使用 Vuex + Vue.js 构建单页应用 的文章,文章主要是介绍 vuex 的基本使用方法,发现对大部 ...

  9. 构建单页Web应用

    摘自前端农民工的博客 让我们先来看几个网站: coding teambition cloud9 注意这几个网站的相同点,那就是在浏览器中,做了原先“应当”在客户端做的事情.它们的界面切换非常流畅,响应 ...

随机推荐

  1. typescript装饰器 方法装饰器 方法参数装饰器 装饰器的执行顺序

    /* 装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为. 通俗的讲装饰器就是一个方法,可以注入到类.方法.属性参数上来扩展类.属性.方法.参数的功能. 常 ...

  2. Python3基础 print 格式化输出 %% 输出%

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  3. 算法习题---4-10洪水(UVa815)

    一:题目 有一个n*m(<=n,m<=)的网格,每个格子都是边长为10米的正方形,网格四周是无限大的墙壁.输入每个格子的海拔高度,以及网格内雨水的总体积,输出水位的海拔高度以及有多少百分比 ...

  4. Hashset(不能添加相同的字符进入数组)

    参考: https://ke.qq.com/webcourse/index.html#cid=434021&term_id=100518216&taid=377652179413386 ...

  5. python web 框架

    Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发. wsgiref模块 wsgiref模块就是python基于wsgi协议(Web Server Ga ...

  6. PyCharm安装及其使用

    1.前提:Python+selenium的安装教程如下网址 https://www.cnblogs.com/linxiu-0925/p/9597634.html 2.PyCharm安装 1.首先去Py ...

  7. AWS 基础设施即代码(五)

    基础设施即代码 概述 手动配置的挑战:可能因为人为错误导致缺乏可靠性,环境无法完全再现,同时需要额外文档 基础设施即代码,是软件开发中用于创建可重用.可维护.可扩展及可测试基础设施的技术.实践和工具, ...

  8. Asp.Net Core中完成拒绝访问功能

    很多时候如果用户没有某个菜单的操作权限的话在页面是不应该显示出来的. @if (SignInManager.IsSignedIn(User) && User.IsInRole(&quo ...

  9. Linux chomd命令

    file 语法为: chmod abc file 其中a,b,c各为一个数字,分别表示User.Group.及Other的权限. r=4,w=2,x=1 若要rwx属性则4+2+1=7: 若要rw-属 ...

  10. LeetCode 896. 单调数列(Monotonic Array)

    896. 单调数列 896. Monotonic Array 题目描述 如果数组是单调递增或单调递减的,那么它是单调的. 如果对于所有 i<=j,A[i]<=A[j],那么数组 A 是单调 ...