├── .babelrc ├── .browserslistrc ├── .gitignore ├── LICENSE ├── README.md ├── dist ├── head │ ├── home.php │ ├── page.php │ └── post.php ├── scripts │ ├── common.05c9bbcf.js │ ├── home-manifest.6b164ac3.js │ ├── home.76569a7b.js │ ├── page-manifest.795b83a9.js │ ├── page.08d56f5f.js │ ├── post-manifest.445a14a6.js │ ├── post.4fb93046.js │ ├── vendors.076adc70.js │ └── vendors.076adc70.js.gz └── styles │ ├── home.bb507fe1.css │ ├── page.eb24e68b.css │ └── post.a3431191.css ├── index.php ├── package.json ├── page.php ├── pnpm-lock.yaml ├── post.php ├── postcss.config.js ├── screenshot.png ├── src ├── main.ts ├── pages │ ├── home │ │ ├── index.ts │ │ └── style.scss │ ├── page │ │ ├── index.ts │ │ └── style.scss │ └── post │ │ ├── index.ts │ │ └── style.scss └── styles │ ├── color.scss │ └── mixins.scss ├── tsconfig.json └── webpack ├── entryAndHtml.ts ├── template.ejs ├── webpack.common.ts ├── webpack.dev.ts └── webpack.prod.ts /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-typescript", 4 | [ 5 | "@babel/env", 6 | { 7 | "useBuiltIns": "usage", //babel 会根据你配置的目标环境,自动引入 polyfill 8 | "corejs": { 9 | "version": 3, 10 | "proposals": true // 使用尚在“提议”阶段特性的 polyfill 11 | } 12 | } 13 | ] 14 | ], 15 | "plugins": ["@babel/plugin-transform-runtime", "@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"] 16 | } 17 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | last 1 version 2 | >1% 3 | # ie>=11 4 | not dead -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 木灵鱼儿 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![ppK0vdO.jpg](https://s1.ax1x.com/2023/03/11/ppK0vdO.jpg) 2 | 3 | ## 说明 4 | 5 | 这是一个用于开发 Typecho 博客主题的的多页面打包项目,支持自动扫描 `src/pages/**/index.ts` 文件作为入口,不需要手动配置 entry 了,但是唯一的缺陷就是目前没办法在启动 watch 监听后再自动获取入口,所以,如果已经开启了 watch 模式,也就是 dev 命令,新增的入口,就得重新启动一次项目,以便重新获取入口。 6 | 7 | 打包出来的文件会以 pages 目录下的文件夹名称作为文件名,生成一个对应名字的 php 文件,这个文件存放着 css 和 js 引入,我们只需要在后续的 php 模板中引入该文件即可,php 文件存放在`dist/head/`下。 8 | 9 | 做这个的初衷也是为了追上现代化开发的步伐,主题的模板开发一直没有什么变化,一方面是是因为整体是 MVC 架构,html 文件只能通过模板的方式进行渲染,这就导致现在的单页面开发那一套不适用,但是我又希望能使用到现代化开发的各种功能,比如 ts、sass 这些东西,然后 js 文件的压缩混淆,于是产生了自己手搓一个工程管理的想法,于是就有了本项目。 10 | 11 | 目前补充了 php 示例文件,可以直接下载丢入 typecho 的主题目录体验,非常简单的 demo 示例 12 | 13 | ## 技术栈 14 | 15 | - webpack5 16 | - typescript 17 | - sass 18 | - postcss 19 | - Babel 20 | - ejs 21 | 22 | 开发所使用的 node 版本为:v18.15.0 23 | 24 | pnpm 包管理器的版本:7.29.1 25 | 26 | ## 基本理念 27 | 28 | 主题是由不同的页面组成,每个页面对应着 src/pages 目录下的一个文件夹,文件夹的名称为页面的名称,比如首页可以命名为 home,home 目录下的 index.ts 文件为该页面的入口文件,这个页面需要使用到的 scss 样式文件,脚本文件,都在这个文件里面引入,具体的业务逻辑也可以写在该文件里面。 29 | 30 | 如果你有 spa 单页应用的开发经验应该是可以很快上手的。 31 | 32 | 由于存在资源的导入路径,为此我加入了路径别名,比如我在 home.ts 中引入与它同级的 styles.scss 样式文件,除了示例中的这种写法: 33 | 34 | ```typescript 35 | import "./style.scss"; 36 | ``` 37 | 38 | 除了这种相对路径,还可以使用路径别名的方式引入: 39 | 40 | ```typescript 41 | import "@/pages/home/style.scss"; 42 | ``` 43 | 44 | `@`表示 src 目录,在 import 引入中都可以使用路径别名来简化引入的路径,减少心智负担。 45 | 46 | ## 启动命令 47 | 48 | 提供了三个命令: 49 | 50 | 1. `pnpm run dev` 用于开发模式,会 watch 监听文件变化自动打包处理 51 | 2. `pnpm run build` 用于构建正式版文件,开发完成使用该命令打包 52 | 3. `pnpm run analyze` 用于代码分析,分析打包后的文件占比以实现对应的优化处理 53 | 54 | ## 功能 55 | 56 | ### typescript 支持 57 | 58 | 支持 ts 文件编译,针对代码也做了 babel 兼容处理,但是默认是以 es6 为兼容标准打包的,如果你需要兼容旧版本浏览器,可以将 `.browserslistrc`文件中的代码改为: 59 | 60 | ```bash 61 | last 1 version 62 | >1% 63 | ie>=11 64 | ``` 65 | 66 | 这样就能兼容到 ie11 了,但是这样的话会导致 js 文件包体变大。 67 | 68 | 当然还可以自定义一些配置,比如兼容安卓什么版本,这个就自行研究吧。 69 | 70 | ### scss 预处理 71 | 72 | 支持 sass 作为 css 的预处理,并增加了全局文件,默认定死为: 73 | 74 | - src\styles\color.scss 75 | - src\styles\mixins.scss 76 | 77 | 一个是全局颜色变量文件,一个是全局混入文件,如果你有其他的需要增加的全局文件,可以打开:`webpack.common.ts` 78 | 79 | 找到 sass-loader 的配置项`additionalData`,按照相同的格式手动添加即可。 80 | 81 | ### postcss 82 | 83 | postcss 目前只增加了自动增加浏览器前缀的处理,它也是根据`.browserslistrc`文件的兼容配置进行处理的,可以自行配置对应的兼容范围,以便加上对应的浏览器前缀。 84 | 85 | 如果有其他需要可以配置`postcss.config.js`文件。 86 | 87 | ## 公共引入 88 | 89 | 分多入口虽然可以将不同的页面的 js 文件完全分割开来,但是不是所有的东西都是独立的,比如可能会封装一些公共的类方法,比如针对 html 的 header 元素的类,或者一些样式字体文件,这些很多页面都会用到。 90 | 91 | 但是每个页面都需要引入一份太麻烦了,可以在`src/main.ts`这个文件中引入,这个文件所有的页面都会用到它。 92 | 93 | 这样就不用重复引入了。 94 | 95 | ## 更改打包后的引入文件地址 96 | 97 | 默认我是使用的字符串拼接的方式将`options->themeUrl; ?>`和打包后的文件路径进行拼接。 98 | 99 | 如果你需要更改这个配置,可以前往:`webpack\entryAndHtml.ts`目录下修改 createHtml 函数下的`publicPath`配置。 100 | 101 | ## 关于.map 文件 102 | 103 | 一般情况下,我们会在开发环境生成 map 文件,而在生产环境是不产生 map 文件的,也就是 build 后我们是不会有 map 文件的,这样有利于代码的保护。 104 | 105 | 但是如果你需要在生产环境生成 map 文件,可以修改`webpack\webpack.prod.ts`文件的`devtool`选项,将其注释放开,值改为: 106 | 107 | ```typescript 108 | { 109 | devtool: "eval", 110 | } 111 | ``` 112 | 113 | 再打包即可。 114 | 115 | ## 优化处理:gzip 和 tree shaking 116 | 117 | 默认已经在`webpack\webpack.prod.ts`文件配置好了,不建议改动,其中 gzip 都有注释,有需要可以看下。 118 | 119 | 而 tree shaking 在官方的定义下,它需要满足三个条件才可以,所以不建议改动`webpack.prod.ts`文件,以免摇树失效。 120 | 121 | 非要改自己遵循 webpack 官方的规则即可。 122 | -------------------------------------------------------------------------------- /dist/head/home.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dist/head/page.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dist/head/post.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /dist/scripts/common.05c9bbcf.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunkwebpack_multiple_entry=self.webpackChunkwebpack_multiple_entry||[]).push([[592],{4535:function(){console.log("大家好,我是通用入口文件")}}]); -------------------------------------------------------------------------------- /dist/scripts/home-manifest.6b164ac3.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var r,n={},e={};function t(r){var o=e[r];if(void 0!==o)return o.exports;var u=e[r]={exports:{}};return n[r](u,u.exports,t),u.exports}t.m=n,r=[],t.O=function(n,e,o,u){if(!e){var i=1/0;for(l=0;l=u)&&Object.keys(t.O).every((function(r){return t.O[r](e[c])}))?e.splice(c--,1):(f=!1,u0&&r[l-1][2]>u;l--)r[l]=r[l-1];r[l]=[e,o,u]},t.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},function(){var r={981:0};t.O.j=function(n){return 0===r[n]};var n=function(n,e){var o,u,i=e[0],f=e[1],c=e[2],a=0;if(i.some((function(n){return 0!==r[n]}))){for(o in f)t.o(f,o)&&(t.m[o]=f[o]);if(c)var l=c(t)}for(n&&n(e);a{alert("异步promise")}))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[592],(function(){return n(4535),n(978)})),e.O()}]); -------------------------------------------------------------------------------- /dist/scripts/page-manifest.795b83a9.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";var r,n={},e={};function t(r){var o=e[r];if(void 0!==o)return o.exports;var u=e[r]={exports:{}};return n[r](u,u.exports,t),u.exports}t.m=n,r=[],t.O=function(n,e,o,u){if(!e){var i=1/0;for(l=0;l=u)&&Object.keys(t.O).every((function(r){return t.O[r](e[c])}))?e.splice(c--,1):(f=!1,u0&&r[l-1][2]>u;l--)r[l]=r[l-1];r[l]=[e,o,u]},t.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},function(){var r={554:0};t.O.j=function(n){return 0===r[n]};var n=function(n,e){var o,u,i=e[0],f=e[1],c=e[2],a=0;if(i.some((function(n){return 0!==r[n]}))){for(o in f)t.o(f,o)&&(t.m[o]=f[o]);if(c)var l=c(t)}for(n&&n(e);a=u)&&Object.keys(e.O).every((function(n){return e.O[n](t[c])}))?t.splice(c--,1):(f=!1,u0&&n[l-1][2]>u;l--)n[l]=n[l-1];n[l]=[t,o,u]},e.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(r,{a:r}),r},e.d=function(n,r){for(var t in r)e.o(r,t)&&!e.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:r[t]})},e.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(n){if("object"==typeof window)return window}}(),e.o=function(n,r){return Object.prototype.hasOwnProperty.call(n,r)},function(){var n={963:0};e.O.j=function(r){return 0===n[r]};var r=function(r,t){var o,u,i=t[0],f=t[1],c=t[2],a=0;if(i.some((function(r){return 0!==n[r]}))){for(o in f)e.o(f,o)&&(e.m[o]=f[o]);if(c)var l=c(e)}for(r&&r(t);a

${e}

${n}

`;const i=document.createElement("div");i.innerHTML=u,document.body.appendChild(i)}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[216,592],(function(){return n(4535),n(5663)})),e.O()}]); -------------------------------------------------------------------------------- /dist/scripts/vendors.076adc70.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunkwebpack_multiple_entry=self.webpackChunkwebpack_multiple_entry||[]).push([[216],{9783:function(t,r,n){var e=n(7838),o=n(1116),i=TypeError;t.exports=function(t){if(e(t))return t;throw i(o(t)+" is not a function")}},2254:function(t,r,n){var e=n(4460).has;t.exports=function(t){return e(t),t}},6325:function(t,r,n){var e=n(1023),o=String,i=TypeError;t.exports=function(t){if(e(t))return t;throw i(o(t)+" is not an object")}},3740:function(t,r,n){var e=n(3046),o=n(7267),i=n(3425),u=function(t){return function(r,n,u){var c,f=e(r),a=i(f),s=o(u,a);if(t&&n!=n){for(;a>s;)if((c=f[s++])!=c)return!0}else for(;a>s;s++)if((t||s in f)&&f[s]===n)return t||s||0;return!t&&-1}};t.exports={includes:u(!0),indexOf:u(!1)}},9561:function(t,r,n){var e=n(9614),o=e({}.toString),i=e("".slice);t.exports=function(t){return i(o(t),8,-1)}},9224:function(t,r,n){var e=n(170),o=n(7838),i=n(9561),u=n(7863)("toStringTag"),c=Object,f="Arguments"==i(function(){return arguments}());t.exports=e?i:function(t){var r,n,e;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,r){try{return t[r]}catch(t){}}(r=c(t),u))?n:f?i(r):"Object"==(e=i(r))&&o(r.callee)?"Arguments":e}},7012:function(t,r,n){var e=n(2682),o=n(1816),i=n(8819),u=n(6977);t.exports=function(t,r,n){for(var c=o(r),f=u.f,a=i.f,s=0;s0&&e[0]<4?1:+(e[0]+e[1])),!o&&u&&(!(e=u.match(/Edge\/(\d+)/))||e[1]>=74)&&(e=u.match(/Chrome\/(\d+)/))&&(o=+e[1]),t.exports=o},4049:function(t){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},3826:function(t,r,n){var e=n(4949),o=n(8819).f,i=n(2196),u=n(5909),c=n(8837),f=n(7012),a=n(2125);t.exports=function(t,r){var n,s,p,v,l,h=t.target,y=t.global,g=t.stat;if(n=y?e:g?e[h]||c(h,{}):(e[h]||{}).prototype)for(s in r){if(v=r[s],p=t.dontCallGetSet?(l=o(n,s))&&l.value:n[s],!a(y?s:h+(g?".":"#")+s,t.forced)&&void 0!==p){if(typeof v==typeof p)continue;f(v,p)}(t.sham||p&&p.sham)&&i(v,"sham",!0),u(n,s,v,t)}}},6094:function(t){t.exports=function(t){try{return!!t()}catch(t){return!0}}},3666:function(t,r,n){var e=n(3020),o=n(9783),i=n(1799),u=e(e.bind);t.exports=function(t,r){return o(t),void 0===r?t:i?u(t,r):function(){return t.apply(r,arguments)}}},1799:function(t,r,n){var e=n(6094);t.exports=!e((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},816:function(t,r,n){var e=n(1799),o=Function.prototype.call;t.exports=e?o.bind(o):function(){return o.apply(o,arguments)}},4108:function(t,r,n){var e=n(6211),o=n(2682),i=Function.prototype,u=e&&Object.getOwnPropertyDescriptor,c=o(i,"name"),f=c&&"something"===function(){}.name,a=c&&(!e||e&&u(i,"name").configurable);t.exports={EXISTS:c,PROPER:f,CONFIGURABLE:a}},3020:function(t,r,n){var e=n(9561),o=n(9614);t.exports=function(t){if("Function"===e(t))return o(t)}},9614:function(t,r,n){var e=n(1799),o=Function.prototype,i=o.call,u=e&&o.bind.bind(i,i);t.exports=e?u:function(t){return function(){return i.apply(t,arguments)}}},3016:function(t,r,n){var e=n(4949),o=n(7838),i=function(t){return o(t)?t:void 0};t.exports=function(t,r){return arguments.length<2?i(e[t]):e[t]&&e[t][r]}},4427:function(t,r,n){var e=n(9224),o=n(9016),i=n(3953),u=n(2680),c=n(7863)("iterator");t.exports=function(t){if(!i(t))return o(t,c)||o(t,"@@iterator")||u[e(t)]}},6504:function(t,r,n){var e=n(816),o=n(9783),i=n(6325),u=n(1116),c=n(4427),f=TypeError;t.exports=function(t,r){var n=arguments.length<2?c(t):r;if(o(n))return i(e(n,t));throw f(u(t)+" is not iterable")}},9016:function(t,r,n){var e=n(9783),o=n(3953);t.exports=function(t,r){var n=t[r];return o(n)?void 0:e(n)}},4949:function(t,r,n){var e=function(t){return t&&t.Math==Math&&t};t.exports=e("object"==typeof globalThis&&globalThis)||e("object"==typeof window&&window)||e("object"==typeof self&&self)||e("object"==typeof n.g&&n.g)||function(){return this}()||Function("return this")()},2682:function(t,r,n){var e=n(9614),o=n(980),i=e({}.hasOwnProperty);t.exports=Object.hasOwn||function(t,r){return i(o(t),r)}},5088:function(t){t.exports={}},8842:function(t,r,n){var e=n(6211),o=n(6094),i=n(2623);t.exports=!e&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},7561:function(t,r,n){var e=n(9614),o=n(6094),i=n(9561),u=Object,c=e("".split);t.exports=o((function(){return!u("z").propertyIsEnumerable(0)}))?function(t){return"String"==i(t)?c(t,""):u(t)}:u},1573:function(t,r,n){var e=n(9614),o=n(7838),i=n(4389),u=e(Function.toString);o(i.inspectSource)||(i.inspectSource=function(t){return u(t)}),t.exports=i.inspectSource},924:function(t,r,n){var e,o,i,u=n(4647),c=n(4949),f=n(1023),a=n(2196),s=n(2682),p=n(4389),v=n(200),l=n(5088),h="Object already initialized",y=c.TypeError,g=c.WeakMap;if(u||p.state){var b=p.state||(p.state=new g);b.get=b.get,b.has=b.has,b.set=b.set,e=function(t,r){if(b.has(t))throw y(h);return r.facade=t,b.set(t,r),r},o=function(t){return b.get(t)||{}},i=function(t){return b.has(t)}}else{var d=v("state");l[d]=!0,e=function(t,r){if(s(t,d))throw y(h);return r.facade=t,a(t,d,r),r},o=function(t){return s(t,d)?t[d]:{}},i=function(t){return s(t,d)}}t.exports={set:e,get:o,has:i,enforce:function(t){return i(t)?o(t):e(t,{})},getterFor:function(t){return function(r){var n;if(!f(r)||(n=o(r)).type!==t)throw y("Incompatible receiver, "+t+" required");return n}}}},8269:function(t,r,n){var e=n(7863),o=n(2680),i=e("iterator"),u=Array.prototype;t.exports=function(t){return void 0!==t&&(o.Array===t||u[i]===t)}},7838:function(t,r,n){var e=n(3769),o=e.all;t.exports=e.IS_HTMLDDA?function(t){return"function"==typeof t||t===o}:function(t){return"function"==typeof t}},2125:function(t,r,n){var e=n(6094),o=n(7838),i=/#|\.prototype\./,u=function(t,r){var n=f[c(t)];return n==s||n!=a&&(o(r)?e(r):!!r)},c=u.normalize=function(t){return String(t).replace(i,".").toLowerCase()},f=u.data={},a=u.NATIVE="N",s=u.POLYFILL="P";t.exports=u},3953:function(t){t.exports=function(t){return null==t}},1023:function(t,r,n){var e=n(7838),o=n(3769),i=o.all;t.exports=o.IS_HTMLDDA?function(t){return"object"==typeof t?null!==t:e(t)||t===i}:function(t){return"object"==typeof t?null!==t:e(t)}},5315:function(t){t.exports=!1},409:function(t,r,n){var e=n(3016),o=n(7838),i=n(4980),u=n(7776),c=Object;t.exports=u?function(t){return"symbol"==typeof t}:function(t){var r=e("Symbol");return o(r)&&i(r.prototype,c(t))}},2770:function(t,r,n){var e=n(816);t.exports=function(t,r,n){for(var o,i,u=n||t.next;!(o=e(u,t)).done;)if(void 0!==(i=r(o.value)))return i}},5978:function(t,r,n){var e=n(3666),o=n(816),i=n(6325),u=n(1116),c=n(8269),f=n(3425),a=n(4980),s=n(6504),p=n(4427),v=n(3513),l=TypeError,h=function(t,r){this.stopped=t,this.result=r},y=h.prototype;t.exports=function(t,r,n){var g,b,d,x,m,w,S,O=n&&n.that,j=!(!n||!n.AS_ENTRIES),M=!(!n||!n.IS_RECORD),E=!(!n||!n.IS_ITERATOR),T=!(!n||!n.INTERRUPTED),P=e(r,O),k=function(t){return g&&v(g,"normal",t),new h(!0,t)},I=function(t){return j?(i(t),T?P(t[0],t[1],k):P(t[0],t[1])):T?P(t,k):P(t)};if(M)g=t.iterator;else if(E)g=t;else{if(!(b=p(t)))throw l(u(t)+" is not iterable");if(c(b)){for(d=0,x=f(t);x>d;d++)if((m=I(t[d]))&&a(y,m))return m;return new h(!1)}g=s(t,b)}for(w=M?t.next:g.next;!(S=o(w,g)).done;){try{m=I(S.value)}catch(t){v(g,"throw",t)}if("object"==typeof m&&m&&a(y,m))return m}return new h(!1)}},3513:function(t,r,n){var e=n(816),o=n(6325),i=n(9016);t.exports=function(t,r,n){var u,c;o(t);try{if(!(u=i(t,"return"))){if("throw"===r)throw n;return n}u=e(u,t)}catch(t){c=!0,u=t}if("throw"===r)throw n;if(c)throw u;return o(u),n}},2680:function(t){t.exports={}},3425:function(t,r,n){var e=n(561);t.exports=function(t){return e(t.length)}},602:function(t,r,n){var e=n(9614),o=n(6094),i=n(7838),u=n(2682),c=n(6211),f=n(4108).CONFIGURABLE,a=n(1573),s=n(924),p=s.enforce,v=s.get,l=String,h=Object.defineProperty,y=e("".slice),g=e("".replace),b=e([].join),d=c&&!o((function(){return 8!==h((function(){}),"length",{value:8}).length})),x=String(String).split("String"),m=t.exports=function(t,r,n){"Symbol("===y(l(r),0,7)&&(r="["+g(l(r),/^Symbol\(([^)]*)\)/,"$1")+"]"),n&&n.getter&&(r="get "+r),n&&n.setter&&(r="set "+r),(!u(t,"name")||f&&t.name!==r)&&(c?h(t,"name",{value:r,configurable:!0}):t.name=r),d&&n&&u(n,"arity")&&t.length!==n.arity&&h(t,"length",{value:n.arity});try{n&&u(n,"constructor")&&n.constructor?c&&h(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(t){}var e=p(t);return u(e,"source")||(e.source=b(x,"string"==typeof r?r:"")),t};Function.prototype.toString=m((function(){return i(this)&&v(this).source||a(this)}),"toString")},4460:function(t,r,n){var e=n(9614),o=Map.prototype;t.exports={Map:Map,set:e(o.set),get:e(o.get),has:e(o.has),remove:e(o.delete),proto:o}},210:function(t,r,n){var e=n(9614),o=n(2770),i=n(4460),u=i.Map,c=i.proto,f=e(c.forEach),a=e(c.entries),s=a(new u).next;t.exports=function(t,r,n){return n?o(a(t),(function(t){return r(t[1],t[0])}),s):f(t,r)}},1905:function(t){var r=Math.ceil,n=Math.floor;t.exports=Math.trunc||function(t){var e=+t;return(e>0?n:r)(e)}},6977:function(t,r,n){var e=n(6211),o=n(8842),i=n(5194),u=n(6325),c=n(4989),f=TypeError,a=Object.defineProperty,s=Object.getOwnPropertyDescriptor,p="enumerable",v="configurable",l="writable";r.f=e?i?function(t,r,n){if(u(t),r=c(r),u(n),"function"==typeof t&&"prototype"===r&&"value"in n&&l in n&&!n[l]){var e=s(t,r);e&&e[l]&&(t[r]=n.value,n={configurable:v in n?n[v]:e[v],enumerable:p in n?n[p]:e[p],writable:!1})}return a(t,r,n)}:a:function(t,r,n){if(u(t),r=c(r),u(n),o)try{return a(t,r,n)}catch(t){}if("get"in n||"set"in n)throw f("Accessors not supported");return"value"in n&&(t[r]=n.value),t}},8819:function(t,r,n){var e=n(6211),o=n(816),i=n(838),u=n(2756),c=n(3046),f=n(4989),a=n(2682),s=n(8842),p=Object.getOwnPropertyDescriptor;r.f=e?p:function(t,r){if(t=c(t),r=f(r),s)try{return p(t,r)}catch(t){}if(a(t,r))return u(!o(i.f,t,r),t[r])}},3621:function(t,r,n){var e=n(8300),o=n(4049).concat("length","prototype");r.f=Object.getOwnPropertyNames||function(t){return e(t,o)}},5590:function(t,r){r.f=Object.getOwnPropertySymbols},4980:function(t,r,n){var e=n(9614);t.exports=e({}.isPrototypeOf)},8300:function(t,r,n){var e=n(9614),o=n(2682),i=n(3046),u=n(3740).indexOf,c=n(5088),f=e([].push);t.exports=function(t,r){var n,e=i(t),a=0,s=[];for(n in e)!o(c,n)&&o(e,n)&&f(s,n);for(;r.length>a;)o(e,n=r[a++])&&(~u(s,n)||f(s,n));return s}},838:function(t,r){"use strict";var n={}.propertyIsEnumerable,e=Object.getOwnPropertyDescriptor,o=e&&!n.call({1:2},1);r.f=o?function(t){var r=e(this,t);return!!r&&r.enumerable}:n},8531:function(t,r,n){var e=n(816),o=n(7838),i=n(1023),u=TypeError;t.exports=function(t,r){var n,c;if("string"===r&&o(n=t.toString)&&!i(c=e(n,t)))return c;if(o(n=t.valueOf)&&!i(c=e(n,t)))return c;if("string"!==r&&o(n=t.toString)&&!i(c=e(n,t)))return c;throw u("Can't convert object to primitive value")}},1816:function(t,r,n){var e=n(3016),o=n(9614),i=n(3621),u=n(5590),c=n(6325),f=o([].concat);t.exports=e("Reflect","ownKeys")||function(t){var r=i.f(c(t)),n=u.f;return n?f(r,n(t)):r}},2726:function(t,r,n){var e=n(3953),o=TypeError;t.exports=function(t){if(e(t))throw o("Can't call method on "+t);return t}},2066:function(t){t.exports=function(t,r){return t===r||t!=t&&r!=r}},200:function(t,r,n){var e=n(1924),o=n(1167),i=e("keys");t.exports=function(t){return i[t]||(i[t]=o(t))}},4389:function(t,r,n){var e=n(4949),o=n(8837),i="__core-js_shared__",u=e[i]||o(i,{});t.exports=u},1924:function(t,r,n){var e=n(5315),o=n(4389);(t.exports=function(t,r){return o[t]||(o[t]=void 0!==r?r:{})})("versions",[]).push({version:"3.29.1",mode:e?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.29.1/LICENSE",source:"https://github.com/zloirock/core-js"})},1776:function(t,r,n){var e=n(1763),o=n(6094);t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol();return!String(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&e&&e<41}))},7267:function(t,r,n){var e=n(7550),o=Math.max,i=Math.min;t.exports=function(t,r){var n=e(t);return n<0?o(n+r,0):i(n,r)}},3046:function(t,r,n){var e=n(7561),o=n(2726);t.exports=function(t){return e(o(t))}},7550:function(t,r,n){var e=n(1905);t.exports=function(t){var r=+t;return r!=r||0===r?0:e(r)}},561:function(t,r,n){var e=n(7550),o=Math.min;t.exports=function(t){return t>0?o(e(t),9007199254740991):0}},980:function(t,r,n){var e=n(2726),o=Object;t.exports=function(t){return o(e(t))}},6802:function(t,r,n){var e=n(816),o=n(1023),i=n(409),u=n(9016),c=n(8531),f=n(7863),a=TypeError,s=f("toPrimitive");t.exports=function(t,r){if(!o(t)||i(t))return t;var n,f=u(t,s);if(f){if(void 0===r&&(r="default"),n=e(f,t,r),!o(n)||i(n))return n;throw a("Can't convert object to primitive value")}return void 0===r&&(r="number"),c(t,r)}},4989:function(t,r,n){var e=n(6802),o=n(409);t.exports=function(t){var r=e(t,"string");return o(r)?r:r+""}},170:function(t,r,n){var e={};e[n(7863)("toStringTag")]="z",t.exports="[object z]"===String(e)},1116:function(t){var r=String;t.exports=function(t){try{return r(t)}catch(t){return"Object"}}},1167:function(t,r,n){var e=n(9614),o=0,i=Math.random(),u=e(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+u(++o+i,36)}},7776:function(t,r,n){var e=n(1776);t.exports=e&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},5194:function(t,r,n){var e=n(6211),o=n(6094);t.exports=e&&o((function(){return 42!=Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},4647:function(t,r,n){var e=n(4949),o=n(7838),i=e.WeakMap;t.exports=o(i)&&/native code/.test(String(i))},7863:function(t,r,n){var e=n(4949),o=n(1924),i=n(2682),u=n(1167),c=n(1776),f=n(7776),a=e.Symbol,s=o("wks"),p=f?a.for||a:a&&a.withoutSetter||u;t.exports=function(t){return i(s,t)||(s[t]=c&&i(a,t)?a[t]:p("Symbol."+t)),s[t]}},80:function(t,r,n){"use strict";var e=n(3826),o=n(2254),i=n(4460).remove;e({target:"Map",proto:!0,real:!0,forced:!0},{deleteAll:function(){for(var t,r=o(this),n=!0,e=0,u=arguments.length;e1?arguments[1]:void 0);return!1!==u(r,(function(t,e){if(!n(t,e,r))return!1}),!0)}})},9884:function(t,r,n){"use strict";var e=n(3826),o=n(3666),i=n(2254),u=n(4460),c=n(210),f=u.Map,a=u.set;e({target:"Map",proto:!0,real:!0,forced:!0},{filter:function(t){var r=i(this),n=o(t,arguments.length>1?arguments[1]:void 0),e=new f;return c(r,(function(t,o){n(t,o,r)&&a(e,o,t)})),e}})},4510:function(t,r,n){"use strict";var e=n(3826),o=n(3666),i=n(2254),u=n(210);e({target:"Map",proto:!0,real:!0,forced:!0},{findKey:function(t){var r=i(this),n=o(t,arguments.length>1?arguments[1]:void 0),e=u(r,(function(t,e){if(n(t,e,r))return{key:e}}),!0);return e&&e.key}})},5433:function(t,r,n){"use strict";var e=n(3826),o=n(3666),i=n(2254),u=n(210);e({target:"Map",proto:!0,real:!0,forced:!0},{find:function(t){var r=i(this),n=o(t,arguments.length>1?arguments[1]:void 0),e=u(r,(function(t,e){if(n(t,e,r))return{value:t}}),!0);return e&&e.value}})},1817:function(t,r,n){"use strict";var e=n(3826),o=n(2066),i=n(2254),u=n(210);e({target:"Map",proto:!0,real:!0,forced:!0},{includes:function(t){return!0===u(i(this),(function(r){if(o(r,t))return!0}),!0)}})},4533:function(t,r,n){"use strict";var e=n(3826),o=n(2254),i=n(210);e({target:"Map",proto:!0,real:!0,forced:!0},{keyOf:function(t){var r=i(o(this),(function(r,n){if(r===t)return{key:n}}),!0);return r&&r.key}})},4161:function(t,r,n){"use strict";var e=n(3826),o=n(3666),i=n(2254),u=n(4460),c=n(210),f=u.Map,a=u.set;e({target:"Map",proto:!0,real:!0,forced:!0},{mapKeys:function(t){var r=i(this),n=o(t,arguments.length>1?arguments[1]:void 0),e=new f;return c(r,(function(t,o){a(e,n(t,o,r),t)})),e}})},3171:function(t,r,n){"use strict";var e=n(3826),o=n(3666),i=n(2254),u=n(4460),c=n(210),f=u.Map,a=u.set;e({target:"Map",proto:!0,real:!0,forced:!0},{mapValues:function(t){var r=i(this),n=o(t,arguments.length>1?arguments[1]:void 0),e=new f;return c(r,(function(t,o){a(e,o,n(t,o,r))})),e}})},4668:function(t,r,n){"use strict";var e=n(3826),o=n(2254),i=n(5978),u=n(4460).set;e({target:"Map",proto:!0,real:!0,arity:1,forced:!0},{merge:function(t){for(var r=o(this),n=arguments.length,e=0;e1?arguments[1]:void 0);return!0===u(r,(function(t,e){if(n(t,e,r))return!0}),!0)}})},416:function(t,r,n){"use strict";var e=n(3826),o=n(9783),i=n(2254),u=n(4460),c=TypeError,f=u.get,a=u.has,s=u.set;e({target:"Map",proto:!0,real:!0,forced:!0},{update:function(t,r){var n=i(this),e=arguments.length;o(r);var u=a(n,t);if(!u&&e<3)throw c("Updating absent value");var p=u?f(n,t):o(e>2?arguments[2]:void 0)(t,n);return s(n,t,r(p,t,n)),n}})}}]); -------------------------------------------------------------------------------- /dist/scripts/vendors.076adc70.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mulingyuer/webpack-multiple-entry/596c002496240fe5a13ca4d4dae62b5d59dce866/dist/scripts/vendors.076adc70.js.gz -------------------------------------------------------------------------------- /dist/styles/home.bb507fe1.css: -------------------------------------------------------------------------------- 1 | body{background-color:red} 2 | -------------------------------------------------------------------------------- /dist/styles/page.eb24e68b.css: -------------------------------------------------------------------------------- 1 | body{background-color:#eee} 2 | -------------------------------------------------------------------------------- /dist/styles/post.a3431191.css: -------------------------------------------------------------------------------- 1 | body{background-color:#ccc} 2 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | <?php $this->archiveTitle([ 23 | 'category' => _t('分类 %s 下的文章'), 24 | 'search' => _t('包含关键字 %s 的文章'), 25 | 'tag' => _t('标签 %s 下的文章'), 26 | 'author' => _t('%s 发布的文章'), 27 | ], '', ' - ');?><?php $this->options->title();?> 28 | need("./dist/head/home.php");?> 29 | 30 | 31 | 这是首页 32 | 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-multiple-entry", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "webpack --config=./webpack/webpack.dev.ts", 8 | "build": "webpack --config=./webpack/webpack.prod.ts", 9 | "analyze": "webpack --config=./webpack/webpack.prod.ts --analyze" 10 | }, 11 | "author": "mulingyuer", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "@babel/cli": "^7.21.0", 15 | "@babel/core": "^7.21.0", 16 | "@babel/plugin-proposal-class-properties": "^7.18.6", 17 | "@babel/plugin-proposal-object-rest-spread": "^7.20.7", 18 | "@babel/plugin-transform-runtime": "^7.21.0", 19 | "@babel/preset-env": "^7.20.2", 20 | "@babel/preset-typescript": "^7.21.0", 21 | "@babel/runtime": "^7.21.0", 22 | "@types/glob": "^8.1.0", 23 | "@types/node": "^18.15.3", 24 | "autoprefixer": "^10.4.14", 25 | "babel-loader": "^9.1.2", 26 | "compression-webpack-plugin": "^10.0.0", 27 | "core-js": "3.29.1", 28 | "css-loader": "^6.7.3", 29 | "glob": "^9.2.1", 30 | "html-webpack-plugin": "^5.5.0", 31 | "mini-css-extract-plugin": "^2.7.3", 32 | "postcss": "^8.4.21", 33 | "postcss-loader": "^7.0.2", 34 | "sass": "^1.59.2", 35 | "sass-loader": "^13.2.0", 36 | "ts-node": "^10.9.1", 37 | "typescript": "^4.9.5", 38 | "webpack": "^5.76.1", 39 | "webpack-bundle-analyzer": "^4.8.0", 40 | "webpack-cli": "^5.0.1", 41 | "webpack-merge": "^5.8.0", 42 | "webpackbar": "^5.0.2" 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /page.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <?php $this->archiveTitle([ 8 | 'category' => _t('分类 %s 下的文章'), 9 | 'search' => _t('包含关键字 %s 的文章'), 10 | 'tag' => _t('标签 %s 下的文章'), 11 | 'author' => _t('%s 发布的文章'), 12 | ], '', ' - ');?><?php $this->options->title();?> 13 | need("./dist/head/page.php");?> 14 | 15 | 16 | 这是page页面,是一个默认的独立页模板文件,用于显示独立页面的内容,如果你想要测试,可以在管理后台新建一个独立页面,然后输入路径访问。 17 | 18 | -------------------------------------------------------------------------------- /post.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <?php $this->archiveTitle([ 8 | 'category' => _t('分类 %s 下的文章'), 9 | 'search' => _t('包含关键字 %s 的文章'), 10 | 'tag' => _t('标签 %s 下的文章'), 11 | 'author' => _t('%s 发布的文章'), 12 | ], '', ' - ');?><?php $this->options->title();?> 13 | need("./dist/head/post.php");?> 14 | 15 | 16 | 这是post页面,是一个文章页面模板文件。 17 | 18 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2023-03-11 14:09:10 4 | * @LastEditTime: 2023-03-11 14:09:10 5 | * @LastEditors: mulingyuer 6 | * @Description: postcss.config 7 | * @FilePath: \webpack-multiple-entry\postcss.config.js 8 | * 怎么可能会有bug!!! 9 | */ 10 | 11 | module.exports = { 12 | plugins: ["autoprefixer"], 13 | }; 14 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mulingyuer/webpack-multiple-entry/596c002496240fe5a13ca4d4dae62b5d59dce866/screenshot.png -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 19:22:40 4 | * @LastEditTime: 2023-03-14 17:21:31 5 | * @LastEditors: mulingyuer 6 | * @Description: 通用入口文件 7 | * @FilePath: \webpack-multiple-entry\src\main.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | 11 | //这里存放通用的内容,比如公共的样式,公共的js等等 12 | 13 | console.log("大家好,我是通用入口文件"); 14 | -------------------------------------------------------------------------------- /src/pages/home/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 19:07:38 4 | * @LastEditTime: 2023-03-14 17:13:02 5 | * @LastEditors: mulingyuer 6 | * @Description: index入口文件 7 | * @FilePath: \webpack-multiple-entry\src\pages\home\index.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import "./style.scss"; 11 | 12 | Promise.resolve().then(() => { 13 | alert("异步promise"); 14 | }); 15 | -------------------------------------------------------------------------------- /src/pages/home/style.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: $red; 3 | } 4 | -------------------------------------------------------------------------------- /src/pages/page/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 21:39:53 4 | * @LastEditTime: 2023-03-14 17:13:52 5 | * @LastEditors: mulingyuer 6 | * @Description: about 7 | * @FilePath: \webpack-multiple-entry\src\pages\page\index.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import "./style.scss"; 11 | 12 | class Page { 13 | public name: string; 14 | 15 | constructor() { 16 | this.name = "page"; 17 | } 18 | 19 | public run(): void { 20 | alert(`独立页面:${this.name}`); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/pages/page/style.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #eee; 3 | } 4 | -------------------------------------------------------------------------------- /src/pages/post/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 23:34:05 4 | * @LastEditTime: 2023-03-14 17:21:59 5 | * @LastEditors: mulingyuer 6 | * @Description: 7 | * @FilePath: \webpack-multiple-entry\src\pages\post\index.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import "./style.scss"; 11 | 12 | const map: Map = new Map(); 13 | map.set("段子1", "全面放开二胎以后……某学生在学校犯错误了,老师让其把家长叫来,学生说家长不在家,舅舅可以么?老师说行。第二天,他背上刚满周岁的小舅奔向学校……"); 14 | map.set("段子2", "名花虽有主,我来松松土!"); 15 | map.set("段子3", "世界上最浪漫的事,就是白日做梦。"); 16 | 17 | let htmlText = ""; 18 | for (let [key, value] of map) { 19 | htmlText += `

${key}

${value}

`; 20 | } 21 | const div = document.createElement("div"); 22 | div.innerHTML = htmlText; 23 | 24 | document.body.appendChild(div); 25 | -------------------------------------------------------------------------------- /src/pages/post/style.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #ccc; 3 | } 4 | -------------------------------------------------------------------------------- /src/styles/color.scss: -------------------------------------------------------------------------------- 1 | // 全局颜色变量 2 | $red: red; 3 | -------------------------------------------------------------------------------- /src/styles/mixins.scss: -------------------------------------------------------------------------------- 1 | // 全局混入 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs" /* Specify what module code is generated. */, 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | "baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */, 31 | "paths": { 32 | "@/*": ["src/*"] 33 | } /* Specify a set of entries that re-map imports to additional lookup locations. */, 34 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 35 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 36 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 37 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 38 | // "resolveJsonModule": true, /* Enable importing .json files */ 39 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 40 | 41 | /* JavaScript Support */ 42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 45 | 46 | /* Emit */ 47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 52 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 53 | // "removeComments": true, /* Disable emitting comments. */ 54 | // "noEmit": true, /* Disable emitting files from a compilation. */ 55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 63 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 64 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 67 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 70 | 71 | /* Interop Constraints */ 72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 73 | "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, 74 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, 75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 76 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 77 | 78 | /* Type Checking */ 79 | "strict": true /* Enable all strict type-checking options. */, 80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 81 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 83 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 85 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 86 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 88 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 93 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 98 | 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 102 | }, 103 | "include": ["src/**/*"], 104 | "exclude": ["node_modules"] 105 | } 106 | -------------------------------------------------------------------------------- /webpack/entryAndHtml.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 19:09:51 4 | * @LastEditTime: 2023-03-14 18:39:03 5 | * @LastEditors: mulingyuer 6 | * @Description: 入口和html模板 7 | * @FilePath: \webpack-multiple-entry\webpack\entryAndHtml.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import type { EntryObject } from "webpack"; 11 | import HtmlWebpackPlugin from "html-webpack-plugin"; 12 | import { resolve } from "path"; 13 | import { globSync } from "glob"; 14 | 15 | //通用的入口文件 16 | const mainEntryPath = resolve(__dirname, "../src/main.ts"); 17 | //入口文件路径 18 | const entryPath = resolve(__dirname, "../src/pages"); 19 | 20 | /** 21 | * @description: 生成入口对象 22 | * @param {*} entry 23 | * @Date: 2022-12-18 19:24:08 24 | * @Author: mulingyuer 25 | */ 26 | export function createEntry() { 27 | const entryObj: EntryObject = {}; 28 | 29 | //获取入口文件数组 30 | const entryArr = globSync("**/index.ts", { 31 | cwd: resolve(__dirname, entryPath), 32 | }); 33 | //遍历得到对象 34 | entryArr.forEach((filePath: string) => { 35 | const fileName = filePath.split(/(\/|\\)/i)[0]; 36 | entryObj[fileName] = [mainEntryPath, resolve(__dirname, entryPath, filePath)]; 37 | }); 38 | return entryObj; 39 | } 40 | 41 | /** 42 | * @description: 生成html模板 43 | * @param {*} entry 44 | * @Date: 2022-12-18 19:24:57 45 | * @Author: mulingyuer 46 | */ 47 | export function createHtml(entry: EntryObject) { 48 | const htmlArr: Array = []; 49 | const keys = Object.keys(entry); 50 | 51 | keys.forEach((key) => { 52 | htmlArr.push( 53 | new HtmlWebpackPlugin({ 54 | template: resolve(__dirname, "./template.ejs"), 55 | filename: `head/${key}.php`, 56 | chunks: [key], 57 | inject: false, //自定义模板不需要自动注入 58 | publicPath: "options->themeUrl; ?>/dist", //拼接php地址 59 | minify: { 60 | removeComments: true, //去除html注释 61 | collapseWhitespace: false, //去除换行 62 | minifyCSS: true, //缩小样式元素和样式属性中css 63 | }, 64 | }) 65 | ); 66 | }); 67 | 68 | return htmlArr; 69 | } 70 | -------------------------------------------------------------------------------- /webpack/template.ejs: -------------------------------------------------------------------------------- 1 | <%= htmlWebpackPlugin.tags.headTags %> 2 | -------------------------------------------------------------------------------- /webpack/webpack.common.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 20:34:21 4 | * @LastEditTime: 2023-03-21 18:56:47 5 | * @LastEditors: mulingyuer 6 | * @Description: webpack基础配置 7 | * @FilePath: \webpack-multiple-entry\webpack\webpack.common.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import type { Configuration } from "webpack"; 11 | import { createEntry, createHtml } from "./entryAndHtml"; 12 | import { resolve } from "path"; 13 | import MiniCssExtractPlugin from "mini-css-extract-plugin"; 14 | import WebpackBar from "webpackbar"; 15 | 16 | //自动获取入口文件 17 | const entry = createEntry(); 18 | 19 | export default { 20 | stats: "errors-only", //控制台输出:只在发生错误时输出 21 | entry: entry, 22 | output: { 23 | clean: true, // 在生成文件之前清空 output 目录 24 | filename: `scripts/[name].[contenthash:8].js`, 25 | path: resolve(__dirname, "../dist"), 26 | }, 27 | module: { 28 | rules: [ 29 | { 30 | test: /\.(t|j)s$/, 31 | use: { 32 | loader: "babel-loader", 33 | }, 34 | }, 35 | { 36 | test: /\.css$/, 37 | use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"], 38 | }, 39 | { 40 | test: /\.s(c|a)ss$/i, 41 | use: [ 42 | MiniCssExtractPlugin.loader, 43 | { 44 | loader: "css-loader", 45 | options: { 46 | //由于@import的问题,引入的文件可能不会被postcss-loader转换,所以回退1位 47 | importLoaders: 1, 48 | }, 49 | }, 50 | "postcss-loader", 51 | { 52 | loader: "sass-loader", 53 | options: { 54 | sassOptions: { 55 | //dart-sass 的 charset 选项默认为 true,我们强烈建议你将其改为 false, 56 | //因为 webpack 并不支持utf-8 以外的文件 57 | charset: false, 58 | }, 59 | //前置scss(全局scss) 60 | additionalData: ` 61 | @import "@/styles/color.scss"; 62 | @import "@/styles/mixins.scss"; 63 | `, 64 | }, 65 | }, 66 | ], 67 | }, 68 | { 69 | test: /\.(png|svg|jpg|jpeg|gif)$/i, 70 | type: "asset", //在导出一个 data URI 和发送一个单独的文件之间自动选择 71 | generator: { 72 | filename: "images/[hash][ext][query]", 73 | }, 74 | }, 75 | { 76 | test: /\.(woff|woff2|eot|ttf|otf)$/i, 77 | type: "asset/resource", 78 | generator: { 79 | filename: "fonts/[hash][ext][query]", 80 | }, 81 | }, 82 | ], 83 | }, 84 | plugins: [ 85 | new WebpackBar({ 86 | name: "🚀 少女祈祷中...", 87 | color: "#1e80ff", 88 | }), 89 | //css样式抽离 90 | new MiniCssExtractPlugin({ 91 | filename: "styles/[name].[contenthash:8].css", //css文件命名 92 | chunkFilename: "chunk-[id].css", //异步样式 93 | }), 94 | ...createHtml(entry), 95 | ], 96 | resolve: { 97 | extensions: [".ts", ".js"], // 解析对文件格式 98 | //路径别名 99 | alias: { 100 | "@": resolve(__dirname, "../src/"), 101 | }, 102 | }, 103 | optimization: { 104 | //提取引导模板 105 | runtimeChunk: { 106 | name: (entrypoint: { name: string }) => `${entrypoint.name}-manifest`, 107 | }, 108 | splitChunks: { 109 | chunks: "all", 110 | cacheGroups: { 111 | default: false, 112 | //node_modules公共代码合并到vendors.js 113 | vendor: { 114 | test: /[\\/]node_modules[\\/]/, 115 | name: "vendors", 116 | chunks: "all", 117 | priority: -10, //权重,vendor优先 118 | }, 119 | //业务共用代码提取 120 | commons: { 121 | test: /[\\/]src[\\/]/, 122 | name: "common", 123 | chunks: "all", 124 | priority: -20, //权重 125 | minChunks: 2, 126 | minSize: 0, 127 | }, 128 | }, 129 | }, 130 | }, 131 | } as Configuration; 132 | -------------------------------------------------------------------------------- /webpack/webpack.dev.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 20:49:25 4 | * @LastEditTime: 2023-03-21 18:56:41 5 | * @LastEditors: mulingyuer 6 | * @Description: webpack dev配置 7 | * @FilePath: \webpack-multiple-entry\webpack\webpack.dev.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import type { Configuration } from "webpack"; 11 | import { merge } from "webpack-merge"; 12 | import common from "./webpack.common"; 13 | 14 | export default merge(common, { 15 | mode: "development", 16 | devtool: "eval", //控制是否生成sourcemap 17 | output: { 18 | filename: `pages/[name].js`, 19 | }, 20 | plugins: [], 21 | watch: true, //监听任何已解析文件的更改 22 | watchOptions: { 23 | aggregateTimeout: 600, //600ms内可以重复保存 24 | poll: 1000, // 每秒检查一次变动 25 | ignored: ["**/node_modules"], //忽略模块文件夹 26 | }, 27 | } as Configuration); 28 | -------------------------------------------------------------------------------- /webpack/webpack.prod.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: mulingyuer 3 | * @Date: 2022-12-18 20:49:25 4 | * @LastEditTime: 2023-03-21 18:56:33 5 | * @LastEditors: mulingyuer 6 | * @Description: webpack prod配置 7 | * @FilePath: \webpack-multiple-entry\webpack\webpack.prod.ts 8 | * 怎么可能会有bug!!! 9 | */ 10 | import type { Configuration } from "webpack"; 11 | import { merge } from "webpack-merge"; 12 | import common from "./webpack.common"; 13 | import CompressionPlugin from "compression-webpack-plugin"; 14 | 15 | export default merge(common, { 16 | mode: "production", 17 | // devtool: "hidden-source-map", //不配置就不会产生map,不然就算是hidden也会产生map文件 18 | plugins: [ 19 | new CompressionPlugin({ 20 | algorithm: "gzip", //压缩算法,默认gzip 21 | test: /\.(js|css)(\?.*)?$/i, //指定什么文件进行压缩 22 | threshold: 10240, //大于10kb就压,默认0kb 23 | // minRatio: 0.8, //压缩比 默认0.8 24 | // deleteOriginalAssets: false, //是否删除压缩的源文件 ,默认false 25 | }), 26 | ], 27 | optimization: { 28 | usedExports: true, //开启tree shaking 29 | }, 30 | } as Configuration); 31 | --------------------------------------------------------------------------------