├── .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 |
3 | 6 |
7 | 首页 8 | 关于 9 |
10 |
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 | --------------------------------------------------------------------------------