├── .browserslistrc
├── src
├── pages
│ ├── common
│ │ ├── footer
│ │ │ ├── index.js
│ │ │ ├── index.html
│ │ │ └── index.css
│ │ ├── header
│ │ │ ├── index.html
│ │ │ ├── index.js
│ │ │ ├── index.css
│ │ │ └── logo.svg
│ │ └── reset.css
│ ├── index
│ │ ├── index.css
│ │ ├── index.js
│ │ └── index.html
│ └── about
│ │ ├── index.css
│ │ ├── index.js
│ │ └── index.html
└── assets
│ └── global.css
├── public
└── favicon.ico
├── .babelrc
├── postcss.config.js
├── pages.js
├── webpack.dev.js
├── README.md
├── webpack.prod.js
├── LICENSE
├── package.json
├── .gitignore
└── webpack.config.js
/.browserslistrc:
--------------------------------------------------------------------------------
1 | last 3 version
2 | > 1%
3 | not ie <= 8
--------------------------------------------------------------------------------
/src/pages/common/footer/index.js:
--------------------------------------------------------------------------------
1 | // 页尾的js代码
2 | import "./index.css";
3 |
--------------------------------------------------------------------------------
/src/pages/common/footer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/global.css:
--------------------------------------------------------------------------------
1 | .main-container{
2 | width: 1000px;
3 | margin: 30px auto;
4 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yjisme/multi-static-pages-webpackproj/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/pages/index/index.css:
--------------------------------------------------------------------------------
1 | /* 首页的css */
2 | .main-container{
3 | text-align: center;
4 | font-size: 2em;
5 | }
--------------------------------------------------------------------------------
/src/pages/about/index.css:
--------------------------------------------------------------------------------
1 | /* 关于页面的css */
2 | .main-container {
3 | text-align: center;
4 | font-size: 2em;
5 | }
6 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "useBuiltIns": "usage",
7 | "corejs": 3
8 | }
9 | ]
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | map: false, //关闭source-map
3 | plugins: {
4 | "postcss-preset-env": {
5 | stage: 0, //哪怕是处于草案阶段的语法,也需要转换
6 | preserve: false,
7 | },
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/src/pages/common/footer/index.css:
--------------------------------------------------------------------------------
1 | /* 页尾的css代码 */
2 | .footer-container{
3 | border-top: 1px solid #ccc;
4 | margin: 0 100px;
5 | text-align: center;
6 | padding: 30px 0;
7 | color: #aaa;
8 | margin-top: 300px;
9 | }
--------------------------------------------------------------------------------
/src/pages/about/index.js:
--------------------------------------------------------------------------------
1 | // 关于页使用的js
2 |
3 | // 引入公共css
4 | import "../common/reset.css";
5 | import "./index.css";
6 | import "@/assets/global.css";
7 |
8 | // 引入页面公共部分的js
9 | import "../common/header";
10 | import "../common/footer";
11 |
12 | console.log("关于我们");
13 |
--------------------------------------------------------------------------------
/src/pages/index/index.js:
--------------------------------------------------------------------------------
1 | // 首页使用的js
2 |
3 | // 引入公共css
4 | import "../common/reset.css";
5 | import "./index.css";
6 | import "@/assets/global.css";
7 |
8 | // 引入页面公共部分的js
9 | import "../common/header";
10 | import "../common/footer";
11 |
12 | console.log("首页");
13 |
--------------------------------------------------------------------------------
/src/pages/common/header/index.html:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/pages.js:
--------------------------------------------------------------------------------
1 | // 多页配置
2 | module.exports = {
3 | // 页面名称(对应 chunk 名)
4 | index: {
5 | js: "./src/pages/index", // 页面入口js
6 | html: "./src/pages/index/index.html", // 页面使用的html模板
7 | out: "index.html", // 输出目录中的页面文件名
8 | },
9 | about: {
10 | js: "./src/pages/about",
11 | html: "./src/pages/about/index.html",
12 | out: "about.html",
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/src/pages/common/header/index.js:
--------------------------------------------------------------------------------
1 | // 头部的js代码
2 | import "./index.css";
3 | import $ from "jquery";
4 |
5 | let pathname = location.pathname;
6 | if (pathname === "/") {
7 | pathname += "index.html";
8 | }
9 | $(".header-nav a").each((i, ele) => {
10 | const href = $(ele).attr("href");
11 | if (pathname === href) {
12 | ele.classList.add("header-nav-active");
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/src/pages/index/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 | <%= require("html-loader!../common/header/index.html") %>
11 | 首页
12 |
13 | <%= require("html-loader!../common/footer/index.html") %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/pages/about/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 | <%= require("html-loader!../common/header/index.html") %>
11 | 关于
12 |
13 | <%= require("html-loader!../common/footer/index.html") %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/pages/common/header/index.css:
--------------------------------------------------------------------------------
1 | /* 头部的css代码 */
2 |
3 | .header-container {
4 | color: #fff;
5 | background-color: #000;
6 | display: flex;
7 | height: 60px;
8 | }
9 |
10 | .header-logo {
11 | display: flex;
12 | align-items: center;
13 | margin-left: 300px;
14 | & img {
15 | width: 100px;
16 | }
17 | }
18 |
19 | .header-nav{
20 | margin-left: 50px;
21 | & a{
22 | padding: 0 30px;
23 | line-height: 60px;
24 | }
25 | }
26 | .header-nav-active{
27 | color: burlywood;
28 | }
29 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const merge = require("webpack-merge");
2 | const baseConfig = require("./webpack.config.js");
3 |
4 | // webpack的开发环境配置,从基本配置中合并
5 | // 合并是利用 webpack-merge 完成的: https://github.com/survivejs/webpack-merge
6 | const devConfig = {
7 | mode: "development",
8 | devtool: "source-map",
9 | devServer: {
10 | open: true,
11 | port: 8080,
12 | proxy: {
13 | // 如果开发环境中有跨域问题,在这里配置代理
14 | },
15 | stats: "minimal",
16 | }
17 | };
18 | module.exports = merge(baseConfig, devConfig);
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 使用webpack搭建的多页应用程序
2 |
3 | 该工程适用于传统的前端开发,它支持多个页面,同样也支持一个页面
4 |
5 | 当你遇到下面类似的场景时,可以考虑使用该工程:
6 |
7 | - 你正在开发一些纯粹的静态页面,页面中有少量`ajax`。比如活动促销页面、抽奖页面等。
8 | - 你正在开发一些`JS`功能,这些代码主要用于制作页面上的一些动态效果,比如利用`jquery`实现轮播图、分页等
9 | - 其他不使用前端框架的工程
10 |
11 |
12 |
13 | ## 使用方法
14 |
15 | 1. 从`git`拉取工程:
16 |
17 | ```
18 | git clone https://github.com/yjisme/multi-static-pages-webpackproj.git
19 | ```
20 |
21 | 2. 安装依赖:
22 |
23 | ```
24 | cd multi-static-pages-webpackproj
25 | npm i
26 | ```
27 |
28 | 3. 运行:
29 |
30 | ```
31 | npm run dev
32 | ```
33 |
34 | 4. 打包:
35 |
36 | ```
37 | npm run build
38 | ```
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const merge = require("webpack-merge");
2 | const baseConfig = require("./webpack.config.js");
3 | const WebpackBundleAnalyzer = require("webpack-bundle-analyzer")
4 | .BundleAnalyzerPlugin;
5 | const CmpressionWebpackPlugin = require("compression-webpack-plugin");
6 | // webpack的生产环境配置,从基本配置中合并
7 | // 合并是利用 webpack-merge 完成的: https://github.com/survivejs/webpack-merge
8 | const prodConfig = {
9 | mode: "production",
10 | devtool: "none",
11 | optimization: {
12 | splitChunks: {
13 | //分包配置
14 | chunks: "all",
15 | cacheGroups: {
16 | styles: {
17 | minSize: 0,
18 | test: /\.css$/,
19 | minChunks: 2,
20 | },
21 | },
22 | },
23 | },
24 | plugins: [new WebpackBundleAnalyzer(), new CmpressionWebpackPlugin()],
25 | };
26 |
27 | module.exports = merge(baseConfig, prodConfig);
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 bangbangji
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "multi-static-pages-webpackproj",
3 | "version": "1.0.0",
4 | "description": "使用webpack搭建的多页应用程序工程",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "webpack-dev-server --config webpack.dev.js",
8 | "build": "webpack --config webpack.prod.js"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/yjisme/multi-static-pages-webpackproj.git"
13 | },
14 | "author": "",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/yjisme/multi-static-pages-webpackproj/issues"
18 | },
19 | "homepage": "https://github.com/yjisme/multi-static-pages-webpackproj#readme",
20 | "devDependencies": {
21 | "@babel/core": "^7.8.4",
22 | "@babel/preset-env": "^7.8.4",
23 | "@types/node": "^14.0.11",
24 | "babel-loader": "^8.0.6",
25 | "clean-webpack-plugin": "^3.0.0",
26 | "compression-webpack-plugin": "^4.0.0",
27 | "copy-webpack-plugin": "^6.0.2",
28 | "core-js": "^3.6.4",
29 | "css-loader": "^3.5.3",
30 | "file-loader": "^6.0.0",
31 | "html-loader": "^1.1.0",
32 | "html-webpack-plugin": "^4.3.0",
33 | "mini-css-extract-plugin": "^0.9.0",
34 | "postcss-loader": "^3.0.0",
35 | "postcss-preset-env": "^6.7.0",
36 | "regenerator-runtime": "^0.13.3",
37 | "style-loader": "^1.2.1",
38 | "url-loader": "^4.1.0",
39 | "webpack": "^4.43.0",
40 | "webpack-bundle-analyzer": "^3.8.0",
41 | "webpack-cli": "^3.3.11",
42 | "webpack-dev-server": "^3.11.0",
43 | "webpack-merge": "^4.2.2"
44 | },
45 | "dependencies": {
46 | "jquery": "^3.5.1"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/pages/common/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html,
7 | body,
8 | div,
9 | span,
10 | applet,
11 | object,
12 | iframe,
13 | h1,
14 | h2,
15 | h3,
16 | h4,
17 | h5,
18 | h6,
19 | p,
20 | blockquote,
21 | pre,
22 | a,
23 | abbr,
24 | acronym,
25 | address,
26 | big,
27 | cite,
28 | code,
29 | del,
30 | dfn,
31 | em,
32 | img,
33 | ins,
34 | kbd,
35 | q,
36 | s,
37 | samp,
38 | small,
39 | strike,
40 | strong,
41 | sub,
42 | sup,
43 | tt,
44 | var,
45 | b,
46 | u,
47 | i,
48 | center,
49 | dl,
50 | dt,
51 | dd,
52 | ol,
53 | ul,
54 | li,
55 | fieldset,
56 | form,
57 | label,
58 | legend,
59 | table,
60 | caption,
61 | tbody,
62 | tfoot,
63 | thead,
64 | tr,
65 | th,
66 | td,
67 | article,
68 | aside,
69 | canvas,
70 | details,
71 | embed,
72 | figure,
73 | figcaption,
74 | footer,
75 | header,
76 | hgroup,
77 | menu,
78 | nav,
79 | output,
80 | ruby,
81 | section,
82 | summary,
83 | time,
84 | mark,
85 | audio,
86 | video {
87 | margin: 0;
88 | padding: 0;
89 | border: 0;
90 | font-size: 100%;
91 | font: inherit;
92 | vertical-align: baseline;
93 | }
94 | /* HTML5 display-role reset for older browsers */
95 | article,
96 | aside,
97 | details,
98 | figcaption,
99 | figure,
100 | footer,
101 | header,
102 | hgroup,
103 | menu,
104 | nav,
105 | section {
106 | display: block;
107 | }
108 | body {
109 | line-height: 1;
110 | }
111 | ol,
112 | ul {
113 | list-style: none;
114 | }
115 | blockquote,
116 | q {
117 | quotes: none;
118 | }
119 | blockquote:before,
120 | blockquote:after,
121 | q:before,
122 | q:after {
123 | content: "";
124 | content: none;
125 | }
126 | table {
127 | border-collapse: collapse;
128 | border-spacing: 0;
129 | }
130 | a {
131 | color: inherit;
132 | text-decoration: none;
133 | }
134 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/src/pages/common/header/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const { CleanWebpackPlugin } = require("clean-webpack-plugin"); // 清除 dist 目录
3 | const CopyPlugin = require("copy-webpack-plugin"); // 处理静态资源
4 | const HtmlWebpackPlugin = require("html-webpack-plugin"); // 处理模板页面
5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 打包css文件
6 | const pages = require("./pages"); // 加载多页配置
7 |
8 | // 获取入口配置
9 | function getEntry() {
10 | const entry = {};
11 | for (const key in pages) {
12 | entry[key] = pages[key].js;
13 | }
14 | return entry;
15 | }
16 |
17 | // 获取针对多页的 HtmlWebpackPlugin 配置
18 | function getHtmlPlugins() {
19 | const plugins = [];
20 | for (const key in pages) {
21 | plugins.push(
22 | new HtmlWebpackPlugin({
23 | chunks: [key], // 使用的chunk
24 | template: path.resolve(__dirname, pages[key].html),
25 | filename: pages[key].out,
26 | })
27 | );
28 | }
29 | return plugins;
30 | }
31 |
32 | // webpack的基本配置
33 | module.exports = {
34 | entry: getEntry(), // 获取入口配置
35 | output: {
36 | filename: "js/[name].[chunkhash:5].js", // js 输出到 dist/js/xxx
37 | publicPath: "/", // 公用的公共路径 /
38 | path: path.resolve(__dirname, "dist"), // 输出目录为 dist
39 | },
40 | resolve: {
41 | alias: {
42 | "@": path.resolve(__dirname, "src"), // 别名 @ = src目录
43 | _: __dirname, // 别名 _ = 工程根目录
44 | },
45 | },
46 | stats: {
47 | colors: true, // 打包时使用不同的颜色区分信息
48 | modules: false, // 打包时不显示具体模块信息
49 | entrypoints: false, // 打包时不显示入口模块信息
50 | children: false, // 打包时不显示子模块信息
51 | },
52 | module: {
53 | rules: [
54 | {
55 | // 各种图片、字体文件,均交给 url-loader 处理
56 | test: /\.(png)|(gif)|(jpg)|(svg)|(bmp)|(eot)|(woff)|(ttf)$/i,
57 | use: [
58 | {
59 | loader: "url-loader",
60 | options: {
61 | limit: 10 * 1024, //只要文件不超过 100*1024 字节,则使用base64编码,否则,交给file-loader进行处理
62 | name: "static/[name].[hash:5].[ext]",
63 | },
64 | },
65 | ],
66 | },
67 | {
68 | // 所有的 css 和 pcss 文件均交给 postcss 处理
69 | test: /\.(css)|(pcss)$/i,
70 | use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"],
71 | },
72 | { test: /\.js$/, use: "babel-loader" },
73 | ],
74 | },
75 | plugins: [
76 | new CleanWebpackPlugin(), // 应用 清除输出目录 插件
77 | new CopyPlugin({
78 | // 应用 复制文件 插件
79 | patterns: [
80 | {
81 | from: path.resolve(__dirname, "public"), // 将public目录中的所有文件
82 | to: "./", // 复制到 输出目录 的根目录
83 | },
84 | ],
85 | }),
86 | ...getHtmlPlugins(), // 应用所有页面模板,输出到指定的目录
87 | new MiniCssExtractPlugin({
88 | // 打包 css 代码 到文件中
89 | filename: "css/[name].css",
90 | chunkFilename: "css/common.[hash:5].css" // 针对公共样式的文件名
91 | }),
92 | ],
93 | };
94 |
--------------------------------------------------------------------------------