├── .gitignore ├── README.md ├── hanke-webpack ├── bin │ └── hanke-webpack.js ├── lib │ ├── Compiler.js │ ├── main.ejs │ └── tempCodeRunnerFile.js ├── package-lock.json └── package.json ├── webpack-go ├── .eslintrc.json ├── dist │ ├── bundle.js │ ├── css │ │ └── main.css │ ├── img │ │ └── 8aa125a36411f9b5c0875f4ee3de2c1c.jpg │ ├── index.html │ ├── main.css │ ├── main.js │ └── tempCodeRunnerFile.js ├── package.json ├── postcss.config.js ├── src │ ├── a.css │ ├── a.js │ ├── index.css │ ├── index.html │ ├── index.js │ ├── index.less │ └── logo.jpg ├── tempCodeRunnerFile.js └── webpack.config.js ├── webpack-go2 ├── dist │ ├── 01.txt │ ├── index.html │ └── index.js ├── doc │ └── 01.txt ├── package.json ├── server.js ├── src │ ├── index.html │ ├── index.js │ ├── other.js │ └── style.css ├── tempCodeRunnerFile.js ├── webpack.config.js ├── webpack.dev.js └── webpack.pro.js ├── webpack-go3 ├── dist │ ├── _dll_react.js │ ├── bundle.js │ ├── index.html │ ├── index.js │ ├── manifest.json │ ├── other.js │ ├── tempCodeRunnerFile.js │ └── test.js ├── package.json ├── public │ └── index.html ├── src │ ├── a.js │ ├── b.js │ ├── index.js │ ├── other.js │ ├── source.js │ └── test.js ├── webpack.config.js └── webpack.react.js ├── webpack-go4 ├── async │ ├── AsyncPrallerHook(case).js │ ├── AsyncPrallerHook.js │ └── tempCodeRunnerFile.js ├── asyncseries │ ├── AsyncSeriesHook(case).js │ ├── AsyncSeriesHook.js │ ├── AsyncSeriesWaterfall(case).js │ ├── AsyncSeriesWaterfall.js │ └── tempCodeRunnerFile.js ├── package.json ├── sync │ ├── case(SyncBailHook).js │ ├── case(SyncHook).js │ ├── case(SyncLoopHook).js │ ├── case(SyncWaterfallHook).js │ ├── start(SyncBailHook).js │ ├── start(SyncHook).js │ ├── start(SyncLoopHook).1.js │ ├── start(SyncWaterfallHook).js │ └── tempCodeRunnerFile.js └── tempCodeRunnerFile.js ├── webpack-go5 ├── dist │ ├── bundle.js │ ├── index.html │ ├── main.js │ └── tempCodeRunnerFile.js ├── loader │ ├── less-loader.js │ └── style-loader.js ├── package.json ├── src │ ├── a.js │ ├── base │ │ └── b.js │ ├── index.js │ └── index.less └── webpack.config.js ├── webpack-go6 ├── banner.js ├── dist │ ├── 9457fbc2cf600903b9863a416cb4b7f4.jpg │ ├── build.js │ ├── build.js.map │ └── index.html ├── loader │ ├── babel-loader.js │ ├── banner-loader.js │ ├── css-loader.js │ ├── file-loader.js │ ├── inline-loader.js │ ├── less-loader.js │ ├── loader1.js │ ├── loader2.js │ ├── loader3.js │ ├── style-loader.js │ ├── tempCodeRunnerFile.js │ └── url-loader.js ├── package.json ├── src │ ├── a.js │ ├── index.js │ ├── index.less │ ├── lala.jpg │ └── tempCodeRunnerFile.js └── webpack.config.js ├── webpack-go7 ├── dist │ └── index.html ├── package.json ├── plugins │ ├── AsyncPlugin.js │ ├── DonePlugin.js │ ├── FileListPlugin.js │ └── InlineSourcePlugin.js ├── src │ ├── index.css │ ├── index.html │ └── index.js └── webpack.config.js └── webpack笔记 ├── webpack学习...01.md ├── webpack学习...02.md ├── webpack学习...03.md ├── webpack学习...04.md ├── webpack学习...05.md ├── webpack学习...06.md └── webpack学习...07.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | .vscode 4 | .git 5 | .DS_store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## readme 2 | 3 | ## ps 4 | 5 | 这是我根据b站webpack视频整理的,由于没有代码和笔记,就自己整理了一下,希望看到的人能够star一个哟 6 | 7 | 视频源地址 []() 8 | 9 | ## webpack-go部分 10 | 11 | > + 这对应着视频的1-11节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 12 | > + 为了方便,所有代码都是在一个index.js编写的 可以按照视频看的顺序来进行查看(有一些出错是因为注释了其中内容) 13 | > + 视频中有一些代码不太适合现在的版本,我就查阅网上或者按照简单的方式来编写了(视频演示的基本注释在js中) 14 | > + webpack笔记中的webpack...学习01对应着这部分,可以配合它以及代码来观看视频 15 | > + 本人是一个菜鸡,肯定会有些错误或者遗漏的地方,请大家多多包涵~ 16 | > + 大家一起加油学习啊! 17 | 18 | ## webpack-go2部分 19 | 20 | > + 这对应着视频的12-19节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 21 | > + 这次的笔记换了一个方式 把小知识点又重新写了一遍(在webpack.config.js中其实都有) 22 | > + webpack笔记中的webpack...学习02对应着这部分,可以配合它以及代码来观看视频 23 | > + 有错误请多多包涵~ 24 | 25 | ## webpack-go3部分 26 | 27 | > - 这对应着视频的20-27节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 28 | > - webpack笔记中的webpack...学习03对应着这部分,可以配合它以及代码来观看视频 29 | > - 有错误请多多包涵~ 30 | 31 | ## webpack-go4部分 32 | 33 | > - 这对应着视频的28-32节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 34 | > - webpack笔记中的webpack...学习04对应着这部分,可以配合它以及代码来观看视频 35 | > - 这次主要是代码以及实现 36 | > - 有错误请多多包涵~ 37 | 38 | ## webpack-go5部分 39 | 40 | > - 这对应着视频的33-39节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 41 | > - 注意hanke-webpack中一开始的使用(可能有不同方法 我按照自己会的来的) 42 | > - webpack笔记中的webpack...学习05对应着这部分,可以配合它以及代码来观看视频 43 | > - 这次主要是代码以及实现 44 | > - 有错误请多多包涵~ 45 | 46 | ## webpack-go6部分 47 | 48 | > - 这对应着视频的40-46节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 49 | > - webpack笔记中的webpack...学习06对应着这部分,可以配合它以及代码来观看视频 50 | > - 这次主要是代码以及实现 51 | > - 有错误请多多包涵~ 52 | 53 | ## webpack-go7部分 54 | 55 | > - 这对应着视频的47-49节 clone后 直接 cnpm i 安装即可(npm i 可能会出错) 56 | > - webpack笔记中的webpack...学习07对应着这部分,可以配合它以及代码来观看视频 57 | > - 这次主要是代码以及实现 58 | > - 有错误请多多包涵~ 59 | > - ps 这次的最后一节的文件上传还没有开始 ,七牛云没用到过,这几天还要编译原理考试,打算之后再看一看,学一学 60 | 61 | ## webpack总结和笔记 62 | 63 | > 在这次学习中用到的方法我打算多复习多应用,会以后继续学习更新的(考试,这几天没时间了o(╥﹏╥)o) 64 | 65 | ## webpack学习到方法和思想 66 | > 突然发现要是这样整理下去的话会变得很多,就把它独立成一个项目了,更多的是面试中常见的问题,希望你们能给一个star哟 67 | 68 | ## 链接 [前端知识整理](https://github.com/1better/fore-end) -------------------------------------------------------------------------------- /hanke-webpack/bin/hanke-webpack.js: -------------------------------------------------------------------------------- 1 | #! F:/nodejs/node.exe 2 | // 表示在node环境下运行 3 | 4 | let path = require('path') 5 | 6 | let config = require(path.resolve('webpack.config.js')) 7 | 8 | let Compiler = require('../lib/Compiler') 9 | 10 | let compiler = new Compiler(config) 11 | 12 | //入口函数 13 | compiler.hooks.entryOption.call() 14 | 15 | compiler.run() 16 | -------------------------------------------------------------------------------- /hanke-webpack/lib/Compiler.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const babylon = require('babylon') 4 | const types = require('@babel/types') 5 | //es6模块 需要.defalut 6 | const traverse = require('@babel/traverse').default 7 | const generator = require('@babel/generator').default 8 | //babelon 把源码解析成AST 9 | //@babel/traverse 遍历节点 10 | //@babel/types 节点替换 11 | //@babel/generator 生成 12 | const {SyncHook } = require('tapable') 13 | const ejs = require('ejs') 14 | //引入ejs 15 | class Compiler{ 16 | constructor(config){ 17 | // entry output 18 | this.config = config 19 | // 保存文件路径 20 | this.entryId //'./src/index.js' 21 | // 保存所有模块依赖 22 | this.modules = {} 23 | this.entry = config.entry 24 | //可能输出多个文件 25 | this.assets = {} 26 | //表示 工作路径 27 | this.root = process.cwd() 28 | //模拟webpack的声明周期 29 | this.hooks = { 30 | entryOption: new SyncHook(), 31 | compile: new SyncHook(), 32 | afterCompile: new SyncHook(), 33 | afterPlugins: new SyncHook(), 34 | run: new SyncHook(), 35 | emit: new SyncHook(), 36 | done: new SyncHook() 37 | } 38 | let plugins = this.config.plugins 39 | //如果是数组 40 | if(Array.isArray(plugins)){ 41 | plugins.forEach(plugin=>{ 42 | plugin.apply(this) 43 | }) 44 | } 45 | this.hooks.afterPlugins.call() 46 | 47 | } 48 | // 得到文件内容 49 | getSource(modulePath) { 50 | let content = fs.readFileSync(modulePath,'utf-8') 51 | //处理 ./index.less 52 | let rules = this.config.module.rules 53 | rules.forEach(rule=>{ 54 | let {test,use} = rule 55 | let len = use.length - 1 56 | if(test.test(modulePath)){ 57 | (function normalLoader() { 58 | //后边是一个绝对路径 59 | let loader = require(use[len--]) 60 | content = loader(content) 61 | if(len>=0){ 62 | normalLoader() 63 | } 64 | })() 65 | 66 | } 67 | }) 68 | 69 | return content 70 | } 71 | // 解析源码 72 | parse(source,parentPath) { //主要靠AST解析语法树 73 | let ast = babylon.parse(source) 74 | let dependencies = []//数组依赖 75 | traverse(ast,{ 76 | // 调用表达式 a执行 require执行 77 | CallExpression(p){ 78 | let node = p.node //对应的节点 79 | if(node.callee.name === 'require') { 80 | node.callee.name = '__webpack_require__' 81 | let moduleName = node.arguments[0].value 82 | moduleName = moduleName + (path.extname(moduleName)? '':'.js') 83 | moduleName = './' + path.join(parentPath,moduleName) //'src/a.js' 84 | dependencies.push(moduleName) 85 | //节点替换 86 | node.arguments = [types.StringLiteral(moduleName)] 87 | } 88 | } 89 | }) 90 | let sourceCode = generator(ast).code 91 | return {sourceCode,dependencies} 92 | } 93 | buildModule(modulePath,isEntry){ 94 | //模块内容 95 | let source = this.getSource(modulePath) 96 | // 模块id moduleName = modulePath - this.root // path.relative对应 此方法 97 | // 这个方法没见到过 记一下 98 | let moduleName = './' + path.relative(this.root,modulePath) 99 | if(isEntry) { 100 | this.entryId = moduleName // 保存入口名字 101 | } 102 | 103 | // 解析 需要把source源码进行改造 返回一个依赖列表 104 | let {sourceCode,dependencies} = this.parse(source,path.dirname(moduleName)) 105 | // 把相对路径和模块中的内容对应起来 106 | this.modules[moduleName] = sourceCode 107 | dependencies.forEach(dep=>{ 108 | //附模块的加载 递归加载 109 | this.buildModule(dep,false) 110 | }) 111 | } 112 | emitFile() { //发射文件 113 | //数据渲染 114 | //看的是webpack.config.js中的output 115 | let main = path.join(this.config.output.path,this.config.output.filename) 116 | //读取模板 117 | let templateStr = this.getSource(path.join(__dirname,'main.ejs')) 118 | //渲染 119 | let code = ejs.render(templateStr,{entryId:this.entryId,modules:this.modules}) 120 | //拿到输出到哪个目录下 121 | //资源中 路径对应的代码 122 | this.assets[main] = code 123 | fs.writeFileSync(main,this.assets[main]) 124 | } 125 | run(){ 126 | //执行 解析文件依赖 127 | //执行 并且创建模块依赖关系 128 | this.hooks.run.call() 129 | //编译 调用 130 | this.hooks.compile.call() 131 | this.buildModule(path.resolve(this.root,this.entry),true) 132 | // 发射一个文件 打包后的文件 133 | this.hooks.afterCompile.call() 134 | this.emitFile() 135 | this.hooks.emit.call() 136 | this.hooks.done.call() 137 | } 138 | } 139 | module.exports = Compiler -------------------------------------------------------------------------------- /hanke-webpack/lib/main.ejs: -------------------------------------------------------------------------------- 1 | (function(modules) { // webpackBootstrap webpack入口函数 2 | var installedModules = {}; 3 | function __webpack_require__(moduleId) { 4 | if(installedModules[moduleId]) { 5 | return installedModules[moduleId].exports; 6 | } 7 | var module = installedModules[moduleId] = { 8 | i: moduleId, 9 | l: false, 10 | exports: {} 11 | }; 12 | modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 13 | return module.exports; 14 | } 15 | return __webpack_require__(__webpack_require__.s = "<%-entryId%>");//入口模块 16 | }) 17 | 18 | ({ 19 | <%for(let key in modules) {%> 20 | "<%-key%>": //key->模块的路径 21 | (function(module, exports,__webpack_require__) { 22 | eval(`<%-modules[key]%>`); 23 | }), 24 | <%}%> 25 | 26 | }); -------------------------------------------------------------------------------- /hanke-webpack/lib/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | const ejs = require('ejs') 2 | console.log(ejs) -------------------------------------------------------------------------------- /hanke-webpack/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hanke-webpack", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /hanke-webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hanke-webpack", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "bin": { 13 | "hanke-webpack": "./bin/hanke-webpack.js" 14 | }, 15 | "devDependencies": { 16 | "babylon": "^6.18.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webpack-go/.eslintrc.json: -------------------------------------------------------------------------------- 1 | /* { 2 | "parserOptions": { 3 | "ecmaVersion": 9, 4 | "sourceType": "module", 5 | "ecmaFeatures": {} 6 | }, 7 | "rules": { 8 | "constructor-super": 2, 9 | "for-direction": 2, 10 | "getter-return": 2, 11 | "no-case-declarations": 2, 12 | "no-class-assign": 2, 13 | "no-compare-neg-zero": 2, 14 | "no-cond-assign": 2, 15 | "no-console": 2, 16 | "no-const-assign": 2, 17 | "no-constant-condition": 2, 18 | "no-control-regex": 2, 19 | "no-debugger": 2, 20 | "no-delete-var": 2, 21 | "no-dupe-args": 2, 22 | "no-dupe-class-members": 2, 23 | "no-dupe-keys": 2, 24 | "no-duplicate-case": 2, 25 | "no-empty": 2, 26 | "no-empty-character-class": 2, 27 | "no-empty-pattern": 2, 28 | "no-ex-assign": 2, 29 | "no-extra-boolean-cast": 2, 30 | "no-extra-semi": 2, 31 | "no-fallthrough": 2, 32 | "no-func-assign": 2, 33 | "no-global-assign": 2, 34 | "no-inner-declarations": 2, 35 | "no-invalid-regexp": 2, 36 | "no-irregular-whitespace": 2, 37 | "no-mixed-spaces-and-tabs": 2, 38 | "no-new-symbol": 2, 39 | "no-obj-calls": 2, 40 | "no-octal": 2, 41 | "no-redeclare": 2, 42 | "no-regex-spaces": 2, 43 | "no-self-assign": 2, 44 | "no-sparse-arrays": 2, 45 | "no-this-before-super": 2, 46 | "no-undef": 2, 47 | "no-unexpected-multiline": 2, 48 | "no-unreachable": 2, 49 | "no-unsafe-finally": 2, 50 | "no-unsafe-negation": 2, 51 | "no-unused-labels": 2, 52 | "no-unused-vars": 2, 53 | "no-useless-escape": 2, 54 | "require-yield": 2, 55 | "use-isnan": 2, 56 | "valid-typeof": 2 57 | }, 58 | "env": {} 59 | } */ -------------------------------------------------------------------------------- /webpack-go/dist/bundle.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./src/index.js": 90 | /*!**********************!*\ 91 | !*** ./src/index.js ***! 92 | \**********************/ 93 | /*! no exports provided */ 94 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 95 | 96 | "use strict"; 97 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _logo_jpg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logo.jpg */ \"./src/logo.jpg\");\n/* harmony import */ var _logo_jpg__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_logo_jpg__WEBPACK_IMPORTED_MODULE_0__);\n// import $ from 'jquery'\n//默认 是 立即执行函数的loader 不会暴露全局变量\n//expose-loader 暴露全局的loader 内联的loader\n//pre post normal \n// 暴露出去 下边是写法规范\n// import $ from 'expose-loader?$!jquery'\n// console.log($)\n//file-loader 图片引入 返回一个新图片地址\n\nconsole.log(_logo_jpg__WEBPACK_IMPORTED_MODULE_0___default.a);\nvar img = new Image();\nimg.src = _logo_jpg__WEBPACK_IMPORTED_MODULE_0___default.a;\ndocument.body.appendChild(img); // require('@babel/polyfill')\n// require(\"./a.js\");\n// console.log(\"ok\");\n// require('./index.css')\n\n__webpack_require__(/*! ./index.less */ \"./src/index.less\"); // let fn = () => {\n// console.log(2222)\n// }\n// fn()\n// function *gen () {\n// yield 1;\n// }\n// console.log(gen().next())\n// console.log('aaa'.includes('a'))\n// class B {\n// c = 2;\n// }\n\n/* @log\r\nclass A {\r\n a = 1;\r\n}\r\nvar a = new A()\r\nconsole.log(a.a)\r\n\r\n//这个装饰 没有学过\r\nfunction log(target) {\r\n console.log(target)\r\n} */\n\n//# sourceURL=webpack:///./src/index.js?"); 98 | 99 | /***/ }), 100 | 101 | /***/ "./src/index.less": 102 | /*!************************!*\ 103 | !*** ./src/index.less ***! 104 | \************************/ 105 | /*! no static exports found */ 106 | /***/ (function(module, exports, __webpack_require__) { 107 | 108 | eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./src/index.less?"); 109 | 110 | /***/ }), 111 | 112 | /***/ "./src/logo.jpg": 113 | /*!**********************!*\ 114 | !*** ./src/logo.jpg ***! 115 | \**********************/ 116 | /*! no static exports found */ 117 | /***/ (function(module, exports) { 118 | 119 | eval("module.exports = \"http:/111/8aa125a36411f9b5c0875f4ee3de2c1c.jpg\";\n\n//# sourceURL=webpack:///./src/logo.jpg?"); 120 | 121 | /***/ }) 122 | 123 | /******/ }); -------------------------------------------------------------------------------- /webpack-go/dist/css/main.css: -------------------------------------------------------------------------------- 1 | body div{width:300px;height:300px;border:1px solid #ccc;-webkit-transform:rotate(45deg);transform:rotate(45deg);background:url(http://http/111/8aa125a36411f9b5c0875f4ee3de2c1c.jpg) no-repeat 50%} -------------------------------------------------------------------------------- /webpack-go/dist/img/8aa125a36411f9b5c0875f4ee3de2c1c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1better/mywebpack/d321b5393ca9d6405fcceceee4e09ada9ec696a3/webpack-go/dist/img/8aa125a36411f9b5c0875f4ee3de2c1c.jpg -------------------------------------------------------------------------------- /webpack-go/dist/index.html: -------------------------------------------------------------------------------- 1 | Document
-------------------------------------------------------------------------------- /webpack-go/dist/main.css: -------------------------------------------------------------------------------- 1 | body div{width:300px;height:300px;border:1px solid #ccc;-webkit-transform:rotate(45deg);transform:rotate(45deg);background:url(img/8aa125a36411f9b5c0875f4ee3de2c1c.jpg) no-repeat 50%} -------------------------------------------------------------------------------- /webpack-go/dist/main.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){n(1),console.log("ok")},function(e,t){console.log("我能行")}]); -------------------------------------------------------------------------------- /webpack-go/dist/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | // expose the modules object (__webpack_modules__) 2 | // __webpack_require__.m = modules; 3 | 4 | // // expose the module cache 5 | // __webpack_require__.c = installedModules; 6 | 7 | // // define getter function for harmony exports 8 | // __webpack_require__.d = function(exports, name, getter) { 9 | // if(!__webpack_require__.o(exports, name)) { 10 | // Object.defineProperty(exports, name, { enumerable: true, get: getter }); 11 | // } 12 | // }; 13 | 14 | // // define __esModule on exports 15 | // __webpack_require__.r = function(exports) { 16 | // if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 17 | // Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 18 | // } 19 | // Object.defineProperty(exports, '__esModule', { value: true }); 20 | // }; 21 | 22 | // // create a fake namespace object 23 | // // mode & 1: value is a module id, require it 24 | // // mode & 2: merge all properties of value into the ns 25 | // // mode & 4: return value when already ns object 26 | // // mode & 8|1: behave like require 27 | // __webpack_require__.t = function(value, mode) { 28 | // if(mode & 1) value = __webpack_require__(value); 29 | // if(mode & 8) return value; 30 | // if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 31 | // var ns = Object.create(null); 32 | // __webpack_require__.r(ns); 33 | // Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 34 | // if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 35 | // return ns; 36 | // }; 37 | 38 | // // getDefaultExport function for compatibility with non-harmony modules 39 | // __webpack_require__.n = function(module) { 40 | // var getter = module && module.__esModule ? 41 | // function getDefault() { return module['default']; } : 42 | // function getModuleExports() { return module; }; 43 | // __webpack_require__.d(getter, 'a', getter); 44 | // return getter; 45 | // }; 46 | 47 | // // Object.prototype.hasOwnProperty.call 48 | // __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 49 | 50 | // // __webpack_public_path__ 51 | // __webpack_require__.p = ""; -------------------------------------------------------------------------------- /webpack-go/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-go", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack", 9 | "dev": "webpack-dev-server --open --port 3000 --hot " 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/core": "^7.4.5", 16 | "@babel/plugin-proposal-class-properties": "^7.4.4", 17 | "@babel/plugin-proposal-decorators": "^7.4.4", 18 | "@babel/plugin-proposal-object-rest-spread": "^7.4.4", 19 | "@babel/plugin-transform-runtime": "^7.4.4", 20 | "@babel/preset-env": "^7.4.5", 21 | "autoprefixer": "^9.5.1", 22 | "babel-loader": "^8.0.6", 23 | "css-loader": "^2.1.1", 24 | "eslint": "^5.16.0", 25 | "eslint-loader": "^2.1.2", 26 | "expose-loader": "^0.7.5", 27 | "file-loader": "^3.0.1", 28 | "html-webpack-plugin": "^3.2.0", 29 | "html-withimg-loader": "^0.1.16", 30 | "jquery": "^3.4.1", 31 | "less": "^3.9.0", 32 | "less-loader": "^5.0.0", 33 | "mini-css-extract-plugin": "^0.7.0", 34 | "optimize-css-assets-webpack-plugin": "^5.0.1", 35 | "postcss-loader": "^3.0.0", 36 | "style-loader": "^0.23.1", 37 | "url-loader": "^1.1.2", 38 | "webpack": "^4.32.2", 39 | "webpack-cli": "^3.3.2", 40 | "webpack-dev-server": "^3.5.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /webpack-go/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require('autoprefixer')] 3 | } -------------------------------------------------------------------------------- /webpack-go/src/a.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: yellow; 3 | } -------------------------------------------------------------------------------- /webpack-go/src/a.js: -------------------------------------------------------------------------------- 1 | console.log('我能行') -------------------------------------------------------------------------------- /webpack-go/src/index.css: -------------------------------------------------------------------------------- 1 | @import './a.css'; 2 | body { 3 | background-color: red; 4 | } -------------------------------------------------------------------------------- /webpack-go/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 13 | 14 | 15 |
16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /webpack-go/src/index.js: -------------------------------------------------------------------------------- 1 | // import $ from 'jquery' 2 | //默认 是 立即执行函数的loader 不会暴露全局变量 3 | //expose-loader 暴露全局的loader 内联的loader 4 | //pre post normal 5 | 6 | // 暴露出去 下边是写法规范 7 | // import $ from 'jquery' 8 | import $ from 'expose-loader?$!jquery' 9 | console.log($) 10 | console.log(window.$) 11 | //file-loader 图片引入 返回一个新图片地址 12 | /* import logo from './logo.jpg' 13 | console.log(logo) 14 | let img = new Image() 15 | img.src = logo 16 | document.body.appendChild(img) */ 17 | 18 | // require('@babel/polyfill') 19 | // require("./a.js"); 20 | 21 | // console.log("ok"); 22 | 23 | // require('./index.css') 24 | // require('./index.less') 25 | 26 | // let fn = () => { 27 | // console.log(2222) 28 | // } 29 | 30 | // fn() 31 | 32 | // function *gen () { 33 | // yield 1; 34 | // } 35 | // console.log(gen().next()) 36 | 37 | 38 | // console.log('aaa'.includes('a')) 39 | 40 | // class B { 41 | // c = 2; 42 | // } 43 | /* @log 44 | class A { 45 | a = 1; 46 | } 47 | var a = new A() 48 | console.log(a.a) 49 | 50 | //这个装饰 没有学过 51 | function log(target) { 52 | console.log(target) 53 | } */ -------------------------------------------------------------------------------- /webpack-go/src/index.less: -------------------------------------------------------------------------------- 1 | body { 2 | div { 3 | width: 300px; 4 | height: 300px; 5 | border: 1px solid #cccccc; 6 | transform: rotate(45deg); 7 | background: url('./logo.jpg') no-repeat center; 8 | } 9 | } -------------------------------------------------------------------------------- /webpack-go/src/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1better/mywebpack/d321b5393ca9d6405fcceceee4e09ada9ec696a3/webpack-go/src/logo.jpg -------------------------------------------------------------------------------- /webpack-go/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | console.log(require.reslove('jquery')) -------------------------------------------------------------------------------- /webpack-go/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWebpackPlugin = require("html-webpack-plugin"); 3 | const MiniCssExtractPlugin = require("mini-css-extract-plugin") 4 | const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 5 | const webpack = require('webpack') 6 | 7 | const htmlPlugin = new HtmlWebpackPlugin({ 8 | template: './src/index.html' ,//模板 9 | filename: 'index.html', 10 | /* //压缩 html 11 | minify: { 12 | //删除属性双引号 13 | removeAttributeQuotes:true, 14 | //变成一行 15 | collapseWhitespace:true, 16 | }, 17 | //有一个hash值 18 | hash : true */ 19 | }) 20 | 21 | const miniPlugin = new MiniCssExtractPlugin({ 22 | // 产生到css目录下 23 | filename: 'css/main.css', 24 | }) 25 | const optPlugin = new OptimizeCSSAssetsPlugin() 26 | const webpackPlugin = new webpack.ProvidePlugin({ 27 | $: 'jquery' 28 | }) 29 | module.exports = { 30 | /* //压缩css文件 这是之前的老版本 现在不行了 31 | optimization: { //优化项 new TerserJSPlugin({}), 32 | minimizer: [ new OptimizeCSSAssetsPlugin({})], 33 | }, */ 34 | /* 35 | 第一种方法 一般不用 直接在package.json中配置就可以 36 | */ 37 | /* devServer: { 38 | //开发服务器的配置 39 | port: 3000, 40 | progress: true, 41 | contentBase: "./src", 42 | //启动gzip压缩 43 | compress: true 44 | }, */ 45 | mode: "development", //模式 46 | entry: "./src/index.js", //入口 47 | output: { 48 | // filename: "bundle.js.[hash:8]", //配置hash :8只显示8位 49 | filename: "bundle.js", //打包后的文件名 50 | path: path.resolve(__dirname, "dist") ,//路径必须是一个绝对路径 51 | // publicPath: 'http://www.hanke.com'//公共的路径 52 | }, 53 | plugins: [ //数组 放着所有webpack的插件 54 | htmlPlugin, 55 | miniPlugin, 56 | //新版本这样压缩就可以了 57 | optPlugin, 58 | //用webpack的插件 在每个模块中 都注入 $ 59 | // webpackPlugin 60 | ], 61 | //引入jquery会忽略掉(已经在cdn引入了) 62 | /* externals: { 63 | jquery: '$' 64 | }, */ 65 | module: { //模块 66 | rules: [ 67 | //配置 html读取img的src 68 | { 69 | test: /\.html$/, 70 | use: 'html-withimg-loader' 71 | }, 72 | //配置 file-loader来读取图片 73 | { 74 | test: /\.(png|jpg|gif)$/, 75 | //做一个限制 当小于多少k 用base64来转化 base64文件可以减少http请求 但是比原文件大3分之1 76 | // 否则用file-loader来产生真实的图片 77 | use: { 78 | loader: 'url-loader', 79 | options: { 80 | limit: 1, 81 | //输出的路径 82 | outputPath: 'img/', 83 | //只在图片中有一个公共的路径 84 | publicPath: 'http:/111' 85 | } 86 | } 87 | }, 88 | { 89 | // 添加loader规则 就不再需要import $ from 'expose-loader?$!jquery' 这样 直接 import 90 | // 这一步一直报错 这个方法显示未定义 不知道为什么 只好用第二个方法 导入插件了 91 | test: require.resolve('jquery'), 92 | use: 'expose-loader?$', 93 | // exclude: /node_modules/ 94 | }, 95 | /* //校验js的 先关闭 最后用到 修改 96 | { 97 | test: /\.js$/,use:[ 98 | { 99 | loader: 'eslint-loader', 100 | options: { 101 | //强制 pre 之前执行 post 之后 未设置为普通的loader 102 | enforce: 'pre' 103 | } 104 | } 105 | ], 106 | exclude: /node_modules/ 107 | }, */ 108 | 109 | //规则 css-loader 处理css文件 解析@import这种语法 110 | // style-loader 把css标签插入到header中 111 | // loader的特点 单一 112 | // loader的用法 字符串只用一个loader 多个需要数组 113 | // loader 的顺序 默认从右到左执行 从下到上执行 114 | /* 115 | test:/\.css$/, use:[ 116 | 'style-loader' 117 | ,'css-loader'] } 118 | */ 119 | // 也可以写成对象,可以多传入一个参数 120 | { 121 | test:/\.css$/, use:[ 122 | { 123 | loader:'style-loader', 124 | options: { 125 | //将style标签插入到顶部 126 | insertAt: 'top' 127 | } 128 | }, 129 | 'css-loader', 130 | 'postcss-loader', 131 | ] 132 | }, 133 | /* //配置less 134 | { 135 | test:/\.less$/, use:[ 136 | { 137 | loader:'style-loader', 138 | options: { 139 | //将style标签插入到顶部 140 | insertAt: 'top' 141 | } 142 | }, 143 | 'css-loader', 144 | 'less-loader' //less -> css 145 | ] 146 | } */ 147 | //抽离为 148 | { 149 | test:/\.less$/, use:[ 150 | MiniCssExtractPlugin.loader, 151 | 'css-loader', 152 | 'postcss-loader', 153 | 'less-loader' //less -> css 154 | ] 155 | }, 156 | /* 配置babel */ 157 | { 158 | test: /\.js$/, 159 | use: [ 160 | { 161 | loader: 'babel-loader', 162 | options: { 163 | presets: [ 164 | '@babel/preset-env' 165 | ], 166 | plugins: [ 167 | // '@babel/plugin-proposal-class-properties' 解析class 168 | // 下边解析 @log 169 | ["@babel/plugin-proposal-decorators", { "legacy": true }], 170 | ['@babel/plugin-proposal-class-properties', { "loose": true}], 171 | '@babel/plugin-transform-runtime' 172 | 173 | ] 174 | } 175 | } 176 | ], 177 | //包括 178 | include: path.resolve(__dirname,'src'), 179 | //排除 180 | exclude: /node_modules/ 181 | 182 | } 183 | ] 184 | } 185 | }; 186 | -------------------------------------------------------------------------------- /webpack-go2/dist/01.txt: -------------------------------------------------------------------------------- 1 | 111 -------------------------------------------------------------------------------- /webpack-go2/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webpack-go2/dist/index.js: -------------------------------------------------------------------------------- 1 | /*! make by hanke ,i will become success! */!function(n){var e={};function r(o){if(e[o])return e[o].exports;var t=e[o]={i:o,l:!1,exports:{}};return n[o].call(t.exports,t,t.exports,r),t.l=!0,t.exports}r.m=n,r.c=e,r.d=function(n,e,o){r.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:o})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,e){if(1&e&&(n=r(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var t in n)r.d(o,t,function(e){return n[e]}.bind(null,t));return o},r.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(e,"a",e),e},r.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},r.p="",r(r.s=0)}([function(module,exports,__webpack_require__){eval("// class B {\n// constructor() {\n// console.log('11111')\n// }\n// }\n// // console.log('a')\n// var b = new B()\n// import 'bootstrap'\n// import './style'\n\n/* let xhr = new XMLHttpRequest()\r\n\r\nxhr.open('GET','/api/user',true)\r\n\r\nxhr.onload = function() {\r\n console.log(xhr.response)\r\n}\r\n\r\nxhr.send() */\nvar url = '';\n\nif (false) {} else {\n url = 'hanke';\n}\n\nconsole.log(url);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL3NyYy9pbmRleC5qcz9iNjM1Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIGNsYXNzIEIge1xyXG4vLyAgIGNvbnN0cnVjdG9yKCkge1xyXG4vLyAgICAgY29uc29sZS5sb2coJzExMTExJylcclxuLy8gICB9XHJcbi8vIH1cclxuLy8gLy8gY29uc29sZS5sb2coJ2EnKVxyXG4vLyB2YXIgYiA9IG5ldyBCKClcclxuLy8gaW1wb3J0ICdib290c3RyYXAnXHJcbi8vIGltcG9ydCAnLi9zdHlsZSdcclxuLyogbGV0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXHJcblxyXG54aHIub3BlbignR0VUJywnL2FwaS91c2VyJyx0cnVlKVxyXG5cclxueGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gIGNvbnNvbGUubG9nKHhoci5yZXNwb25zZSlcclxufVxyXG5cclxueGhyLnNlbmQoKSAqL1xyXG5sZXQgdXJsID0gJydcclxuaWYoREVWPT09J2RldicpIHtcclxuICB1cmwgPSAnbG9jYWxob3N0J1xyXG59ZWxzZSB7XHJcbiAgdXJsID0gJ2hhbmtlJ1xyXG59XHJcblxyXG5jb25zb2xlLmxvZyh1cmwpIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7Ozs7Ozs7O0FBUUE7QUFDQTtBQUFBLGFBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///0\n")}]); -------------------------------------------------------------------------------- /webpack-go2/doc/01.txt: -------------------------------------------------------------------------------- 1 | 111 -------------------------------------------------------------------------------- /webpack-go2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-go2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "webpack-dev-server --open --port 3000 --hot ", 9 | "build": "webpack" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/core": "^7.4.5", 16 | "@babel/preset-env": "^7.4.5", 17 | "babel-loader": "^8.0.6", 18 | "clean-webpack-plugin": "^3.0.0", 19 | "copy-webpack-plugin": "^5.0.3", 20 | "css-loader": "^2.1.1", 21 | "html-webpack-plugin": "^3.2.0", 22 | "style-loader": "^0.23.1", 23 | "webpack": "^4.32.2", 24 | "webpack-cli": "^3.3.2", 25 | "webpack-dev-middleware": "^3.7.0", 26 | "webpack-dev-server": "^3.5.1", 27 | "webpack-merge": "^4.2.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /webpack-go2/server.js: -------------------------------------------------------------------------------- 1 | //webpack自带一个express 2 | let express = require('express') 3 | 4 | let app = express() 5 | 6 | let webpack = require('webpack') 7 | 8 | //需要使用中间件 9 | let middle = require('webpack-dev-middleware') 10 | 11 | let config = require('./webpack.config.js') 12 | 13 | let compiler = webpack(config) 14 | 15 | app.use(middle(compiler)) 16 | 17 | app.get('/api/user',(req,res)=>{ 18 | res.json({ 19 | name: 'myname222' 20 | }) 21 | }) 22 | 23 | app.listen(3500) -------------------------------------------------------------------------------- /webpack-go2/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webpack-go2/src/index.js: -------------------------------------------------------------------------------- 1 | // class B { 2 | // constructor() { 3 | // console.log('11111') 4 | // } 5 | // } 6 | // // console.log('a') 7 | // var b = new B() 8 | // import 'bootstrap' 9 | // import './style' 10 | /* let xhr = new XMLHttpRequest() 11 | 12 | xhr.open('GET','/api/user',true) 13 | 14 | xhr.onload = function() { 15 | console.log(xhr.response) 16 | } 17 | 18 | xhr.send() */ 19 | let url = '' 20 | if(DEV==='dev') { 21 | url = 'localhost' 22 | }else { 23 | url = 'hanke' 24 | } 25 | 26 | console.log(url) -------------------------------------------------------------------------------- /webpack-go2/src/other.js: -------------------------------------------------------------------------------- 1 | console.log('b') -------------------------------------------------------------------------------- /webpack-go2/src/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: yellow; 3 | } -------------------------------------------------------------------------------- /webpack-go2/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | //webpack自带一个express 2 | let express = require('express') 3 | 4 | let app = express() 5 | 6 | // let webpack = require('webpack') 7 | 8 | //需要使用中间件 9 | // let middle = require('webpack-dev-middleware') 10 | 11 | // let config = require('./webpack.config.js') 12 | 13 | // let compiler = webpack(config) 14 | 15 | // app.use(middle(compiler)) 16 | 17 | app.get('/api/user',(req,res)=>{ 18 | res.json({ 19 | name: 'myname222' 20 | }) 21 | }) 22 | 23 | app.listen(3500) -------------------------------------------------------------------------------- /webpack-go2/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const HtmlWpackPlugin = require('html-webpack-plugin') 3 | //内置插件 版权归谁谁谁所有 先导入webpack 4 | const webpack = require('webpack') 5 | 6 | 7 | //copy插件 8 | const copyWpackPlugin = require('copy-webpack-plugin') 9 | 10 | // bannerPlugin 版权声明 11 | const bannerPlugin = new webpack.BannerPlugin('make by hanke ,i will become success!') 12 | // 这个是错误写法 正确写法 应该是解构赋值那样写 说明这个插件包含许多东西 13 | // const CleanWebpackPlugin = require('clean-webpack-plugin') 14 | const { CleanWebpackPlugin } = require('clean-webpack-plugin') 15 | 16 | //拷贝文件 17 | const copyPlugin = new copyWpackPlugin( 18 | //接受一个数组 可以多个文件 19 | [{from:'./doc',to:'./'}] 20 | ) 21 | 22 | // 三个其他的小插件 23 | // 1. cleanWebpackPlugin // 每次打包会把dist目录下的文件都删除 重新打包 24 | // 2. copyWebpackPlugin 25 | // 3. bannerPlugin 26 | // 前两个 需要第三方模块 第三个内置 27 | 28 | 29 | // 判断开发环境的插件 DefinePlugin 30 | const definePlugin = new webpack.DefinePlugin({ 31 | DEV: JSON.stringify('production') 32 | }) 33 | // 也可以传入一个数组 告诉清理哪些文件夹 34 | const cleanPlugin = new CleanWebpackPlugin() 35 | 36 | const htmlPlugin1 = new HtmlWpackPlugin({ 37 | template: './src/index.html', 38 | //多个 html 39 | filename: 'home.html', 40 | //代码块 41 | chunks: ['home'] 42 | }) 43 | const htmlPlugin2 = new HtmlWpackPlugin({ 44 | template: './src/index.html', 45 | //多个 html 46 | filename: 'other.html', 47 | //代码块 放置引入的东西 48 | chunks: ['other'] 49 | }) 50 | 51 | const htmlPlugin = new HtmlWpackPlugin({ 52 | template: './src/index.html', 53 | //多个 html 54 | filename: 'index.html', 55 | }) 56 | module.exports = { 57 | //多入口需要写成一个对象 58 | //两个入口 59 | mode: 'development', 60 | entry: { 61 | /* //首页 62 | home: './src/index.js', 63 | //other页相关 64 | other: './src/other.js' */ 65 | 66 | index: './src/index.js' 67 | }, 68 | //两个出口 69 | output:{ 70 | // name代表 home或者other .[hash] 给文件加一个hash串 71 | // filename: '[name].[hash].js', 72 | filename: '[name].js', 73 | path: path.resolve(__dirname,'dist') 74 | }, 75 | /* //监控 实时打包 类似node里边那个实时监控的 76 | watch: true, 77 | //监控的选项 78 | watchOptions: { 79 | poll: 1000, //每秒问1000次 80 | aggregateTimeout: 500 ,//防抖 (类似于函数防抖) 81 | ignored: /node_modules/ //忽略哪个文件 82 | }, */ 83 | //增加 devtool 源码映射 可以很方便的调试源代码 84 | // 源码映射 单独生成一个 source-map文件 出错会标识出错的列和行 大和全 85 | // devtool:'source-map', 86 | 87 | // 不会单独生成一个文件 但会显示行和列 88 | // devtool: 'eval-source-map', 89 | 90 | // 不会产生单独列 但会生成一个映射文件 91 | //devtool: 'cheap-module-source-map', //保留 后来调试用 92 | // 不会单独生成文件 集成在打包文件中 也不产生列 93 | devtool: 'cheap-module-eval-source-map', 94 | plugins: [ 95 | // 打包多页面 96 | // htmlPlugin1, 97 | // htmlPlugin2 98 | 99 | //学习 source-map使用 100 | htmlPlugin, 101 | // 清除插件 102 | cleanPlugin, 103 | // 复制插件 104 | copyPlugin, 105 | // 内置插件 添加注释 106 | bannerPlugin, 107 | // 内置插件 判断开发环境 108 | definePlugin 109 | ], 110 | //解析第三方模块 commen 111 | resolve: { 112 | //指定解析的模块 113 | modules: [path.resolve('node_modules')], 114 | //或者用 mainFields 入口的字段 先找style 再找main 115 | // mainFiles: [],//入口文件的名字 默认找index.js 116 | mainFields: ['style','main'], 117 | //扩展名 可以省略 需配置 extensions 依次解析 118 | extensions: ['.js','.css','.json'] 119 | //别名 如 vue的vue-runtime和那个@ 120 | // alias: { 121 | // bootstrap: 'bootstrap/dist/css/bootstrap.css' 122 | // } 123 | }, 124 | module: { 125 | rules: [ 126 | { 127 | test: /\.css$/, 128 | use:['style-loader','css-loader'] 129 | }, 130 | { 131 | test: /\.js$/, 132 | use: { 133 | loader: 'babel-loader', 134 | options: { 135 | presets: ['@babel/preset-env'] 136 | } 137 | }, 138 | exclude: /node_modules/ 139 | } 140 | ] 141 | }, 142 | //跨域问题的设置 143 | devServer:{ 144 | //这是 服务器为 /api/user 145 | /* proxy : { 146 | '/api':'http://localhost:3500' 147 | } */ 148 | // /user的用法 149 | /* proxy: { 150 | // 重写的方式 把请求代理到express服务器上 151 | '/api': { 152 | target: 'http://localhost:3500', 153 | pathRewrite: { 154 | '/api':'/' 155 | } 156 | } 157 | } */ 158 | //前端只想单纯模拟方法 159 | /* before(app){ //提供的方法 相当于钩子 160 | //写这些代码就不存在跨域问题 161 | app.get('/user',(req,res)=>{ 162 | res.json({ 163 | name: 'myname-before' 164 | }) 165 | }) 166 | } */ 167 | //有服务端,但是不用代理来处理 在服务器端开启webpack 端口用服务端端口 168 | } 169 | } -------------------------------------------------------------------------------- /webpack-go2/webpack.dev.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1better/mywebpack/d321b5393ca9d6405fcceceee4e09ada9ec696a3/webpack-go2/webpack.dev.js -------------------------------------------------------------------------------- /webpack-go2/webpack.pro.js: -------------------------------------------------------------------------------- 1 | let {smart} = require('webpack-merge') 2 | let base = require('./webpack.config.js') 3 | 4 | module.exports = smart(base,{ 5 | mode:'production' 6 | }) -------------------------------------------------------------------------------- /webpack-go3/dist/bundle.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./src/index.js": 90 | /*!**********************!*\ 91 | !*** ./src/index.js ***! 92 | \**********************/ 93 | /*! no exports provided */ 94 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 95 | 96 | "use strict"; 97 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _test__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./test */ \"./src/test.js\");\n/* // import jquery from 'jquery'\r\n\r\nimport moment from 'moment'\r\n\r\n//加入 ignorePlugin之后就不起作用了 \r\n// moment.locale('zh-cn')\r\n\r\n//自己手动引入所需要的语言包\r\nimport 'moment/locale/zh-cn'\r\n\r\nlet r = moment().endOf('day').fromNow()\r\n\r\nconsole.log(r) */\n\n/* import React from 'react'\r\nimport {render} from 'react-dom'\r\n\r\nrender(\r\n

jsx

,\r\n //这个默认的是那个root\r\n window.root\r\n) */\n\nconsole.log(_test__WEBPACK_IMPORTED_MODULE_0__[\"default\"].sum(1, 2));\n\n//# sourceURL=webpack:///./src/index.js?"); 98 | 99 | /***/ }), 100 | 101 | /***/ "./src/test.js": 102 | /*!*********************!*\ 103 | !*** ./src/test.js ***! 104 | \*********************/ 105 | /*! exports provided: default */ 106 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 107 | 108 | "use strict"; 109 | eval("__webpack_require__.r(__webpack_exports__);\n// module.exports = 'hankewudi'\nfunction sum(a, b) {\n return a + b;\n}\n\nfunction mins(a, b) {\n return a - b;\n}\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n sum: sum,\n mins: mins\n});\n\n//# sourceURL=webpack:///./src/test.js?"); 110 | 111 | /***/ }) 112 | 113 | /******/ }); -------------------------------------------------------------------------------- /webpack-go3/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /webpack-go3/dist/index.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./src/a.js": 90 | /*!******************!*\ 91 | !*** ./src/a.js ***! 92 | \******************/ 93 | /*! no static exports found */ 94 | /***/ (function(module, exports) { 95 | 96 | eval("console.log('a');\n\n//# sourceURL=webpack:///./src/a.js?"); 97 | 98 | /***/ }), 99 | 100 | /***/ "./src/b.js": 101 | /*!******************!*\ 102 | !*** ./src/b.js ***! 103 | \******************/ 104 | /*! no static exports found */ 105 | /***/ (function(module, exports) { 106 | 107 | eval("console.log('b');\n\n//# sourceURL=webpack:///./src/b.js?"); 108 | 109 | /***/ }), 110 | 111 | /***/ "./src/index.js": 112 | /*!**********************!*\ 113 | !*** ./src/index.js ***! 114 | \**********************/ 115 | /*! no exports provided */ 116 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 117 | 118 | "use strict"; 119 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a */ \"./src/a.js\");\n/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_a__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./b */ \"./src/b.js\");\n/* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_b__WEBPACK_IMPORTED_MODULE_1__);\n/* // import jquery from 'jquery'\r\n\r\nimport moment from 'moment'\r\n\r\n//加入 ignorePlugin之后就不起作用了 \r\n// moment.locale('zh-cn')\r\n\r\n//自己手动引入所需要的语言包\r\nimport 'moment/locale/zh-cn'\r\n\r\nlet r = moment().endOf('day').fromNow()\r\n\r\nconsole.log(r) */\n\n/* import React from 'react'\r\nimport {render} from 'react-dom'\r\n\r\nrender(\r\n

jsx

,\r\n //这个默认的是那个root\r\n window.root\r\n) */\n\n/* import calc from './test'\r\n// import 在生产环境下会自动清除没用的东西\r\n// 相当于tree-shaking 没用代码自动删除\r\n// import 可以 但是 require就不行\r\nconsole.log(calc.sum(1,2))\r\n// scope hosting 作用域提升 \r\n// let a = 1\r\n// let b = 2\r\n// let c = 3\r\n// let d = a+b+c //webpack会自动省略可以简化的代码\r\n // console.log(d+'------') */\n\n\nconsole.log('index.js');\n\n//# sourceURL=webpack:///./src/index.js?"); 120 | 121 | /***/ }) 122 | 123 | /******/ }); -------------------------------------------------------------------------------- /webpack-go3/dist/manifest.json: -------------------------------------------------------------------------------- 1 | {"name":"_dll_react","content":{"./node_modules/_react-dom@16.8.6@react-dom/index.js":{"id":"./node_modules/_react-dom@16.8.6@react-dom/index.js","buildMeta":{"providedExports":true}},"./node_modules/_react@16.8.6@react/cjs/react.development.js":{"id":"./node_modules/_react@16.8.6@react/cjs/react.development.js","buildMeta":{"providedExports":true}},"./node_modules/_object-assign@4.1.1@object-assign/index.js":{"id":"./node_modules/_object-assign@4.1.1@object-assign/index.js","buildMeta":{"providedExports":true}},"./node_modules/_prop-types@15.7.2@prop-types/checkPropTypes.js":{"id":"./node_modules/_prop-types@15.7.2@prop-types/checkPropTypes.js","buildMeta":{"providedExports":true}},"./node_modules/_prop-types@15.7.2@prop-types/lib/ReactPropTypesSecret.js":{"id":"./node_modules/_prop-types@15.7.2@prop-types/lib/ReactPropTypesSecret.js","buildMeta":{"providedExports":true}},"./node_modules/_react@16.8.6@react/index.js":{"id":"./node_modules/_react@16.8.6@react/index.js","buildMeta":{"providedExports":true}},"./node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom.development.js":{"id":"./node_modules/_react-dom@16.8.6@react-dom/cjs/react-dom.development.js","buildMeta":{"providedExports":true}},"./node_modules/_scheduler@0.13.6@scheduler/index.js":{"id":"./node_modules/_scheduler@0.13.6@scheduler/index.js","buildMeta":{"providedExports":true}},"./node_modules/_scheduler@0.13.6@scheduler/cjs/scheduler.development.js":{"id":"./node_modules/_scheduler@0.13.6@scheduler/cjs/scheduler.development.js","buildMeta":{"providedExports":true}},"./node_modules/_webpack@4.33.0@webpack/buildin/global.js":{"id":"./node_modules/_webpack@4.33.0@webpack/buildin/global.js","buildMeta":{"providedExports":true}},"./node_modules/_scheduler@0.13.6@scheduler/tracing.js":{"id":"./node_modules/_scheduler@0.13.6@scheduler/tracing.js","buildMeta":{"providedExports":true}},"./node_modules/_scheduler@0.13.6@scheduler/cjs/scheduler-tracing.development.js":{"id":"./node_modules/_scheduler@0.13.6@scheduler/cjs/scheduler-tracing.development.js","buildMeta":{"providedExports":true}}}} -------------------------------------------------------------------------------- /webpack-go3/dist/other.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/other.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./src/a.js": 90 | /*!******************!*\ 91 | !*** ./src/a.js ***! 92 | \******************/ 93 | /*! no static exports found */ 94 | /***/ (function(module, exports) { 95 | 96 | eval("console.log('a');\n\n//# sourceURL=webpack:///./src/a.js?"); 97 | 98 | /***/ }), 99 | 100 | /***/ "./src/b.js": 101 | /*!******************!*\ 102 | !*** ./src/b.js ***! 103 | \******************/ 104 | /*! no static exports found */ 105 | /***/ (function(module, exports) { 106 | 107 | eval("console.log('b');\n\n//# sourceURL=webpack:///./src/b.js?"); 108 | 109 | /***/ }), 110 | 111 | /***/ "./src/other.js": 112 | /*!**********************!*\ 113 | !*** ./src/other.js ***! 114 | \**********************/ 115 | /*! no exports provided */ 116 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 117 | 118 | "use strict"; 119 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a */ \"./src/a.js\");\n/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_a__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./b */ \"./src/b.js\");\n/* harmony import */ var _b__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_b__WEBPACK_IMPORTED_MODULE_1__);\n\n\nconsole.log('other.js');\n\n//# sourceURL=webpack:///./src/other.js?"); 120 | 121 | /***/ }) 122 | 123 | /******/ }); -------------------------------------------------------------------------------- /webpack-go3/dist/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | var a = (function(modules) { // webpackBootstrap 2 | // The module cache 3 | var installedModules = {}; 4 | // The require function 5 | function __webpack_require__(moduleId) { 6 | 7 | // Check if module is in cache 8 | if(installedModules[moduleId]) { 9 | return installedModules[moduleId].exports; 10 | } 11 | // Create a new module (and put it into the cache) 12 | var module = installedModules[moduleId] = { 13 | i: moduleId, 14 | l: false, 15 | exports: {} 16 | }; 17 | 18 | // Execute the module function 19 | modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 20 | 21 | // Flag the module as loaded 22 | module.l = true; 23 | 24 | // Return the exports of the module 25 | return module.exports; 26 | } 27 | return __webpack_require__(__webpack_require__.s = "./src/test.js"); 28 | }) 29 | /************************************************************************/ 30 | ({ 31 | 32 | /***/ "./src/test.js": 33 | /*!*********************!*\ 34 | !*** ./src/test.js ***! 35 | \*********************/ 36 | /*! no static exports found */ 37 | /***/ (function(module, exports) { 38 | 39 | eval("\r\nmodule.exports = 'hankewudi'\n\n//# sourceURL=webpack:///./src/test.js?"); 40 | 41 | /***/ }) 42 | 43 | }); 44 | 45 | console.log(a) -------------------------------------------------------------------------------- /webpack-go3/dist/test.js: -------------------------------------------------------------------------------- 1 | exports["ab"] = 2 | /******/ (function(modules) { // webpackBootstrap 3 | /******/ // The module cache 4 | /******/ var installedModules = {}; 5 | /******/ 6 | /******/ // The require function 7 | /******/ function __webpack_require__(moduleId) { 8 | /******/ 9 | /******/ // Check if module is in cache 10 | /******/ if(installedModules[moduleId]) { 11 | /******/ return installedModules[moduleId].exports; 12 | /******/ } 13 | /******/ // Create a new module (and put it into the cache) 14 | /******/ var module = installedModules[moduleId] = { 15 | /******/ i: moduleId, 16 | /******/ l: false, 17 | /******/ exports: {} 18 | /******/ }; 19 | /******/ 20 | /******/ // Execute the module function 21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 22 | /******/ 23 | /******/ // Flag the module as loaded 24 | /******/ module.l = true; 25 | /******/ 26 | /******/ // Return the exports of the module 27 | /******/ return module.exports; 28 | /******/ } 29 | /******/ 30 | /******/ 31 | /******/ // expose the modules object (__webpack_modules__) 32 | /******/ __webpack_require__.m = modules; 33 | /******/ 34 | /******/ // expose the module cache 35 | /******/ __webpack_require__.c = installedModules; 36 | /******/ 37 | /******/ // define getter function for harmony exports 38 | /******/ __webpack_require__.d = function(exports, name, getter) { 39 | /******/ if(!__webpack_require__.o(exports, name)) { 40 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 41 | /******/ } 42 | /******/ }; 43 | /******/ 44 | /******/ // define __esModule on exports 45 | /******/ __webpack_require__.r = function(exports) { 46 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 47 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 48 | /******/ } 49 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 50 | /******/ }; 51 | /******/ 52 | /******/ // create a fake namespace object 53 | /******/ // mode & 1: value is a module id, require it 54 | /******/ // mode & 2: merge all properties of value into the ns 55 | /******/ // mode & 4: return value when already ns object 56 | /******/ // mode & 8|1: behave like require 57 | /******/ __webpack_require__.t = function(value, mode) { 58 | /******/ if(mode & 1) value = __webpack_require__(value); 59 | /******/ if(mode & 8) return value; 60 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 61 | /******/ var ns = Object.create(null); 62 | /******/ __webpack_require__.r(ns); 63 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 64 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 65 | /******/ return ns; 66 | /******/ }; 67 | /******/ 68 | /******/ // getDefaultExport function for compatibility with non-harmony modules 69 | /******/ __webpack_require__.n = function(module) { 70 | /******/ var getter = module && module.__esModule ? 71 | /******/ function getDefault() { return module['default']; } : 72 | /******/ function getModuleExports() { return module; }; 73 | /******/ __webpack_require__.d(getter, 'a', getter); 74 | /******/ return getter; 75 | /******/ }; 76 | /******/ 77 | /******/ // Object.prototype.hasOwnProperty.call 78 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 79 | /******/ 80 | /******/ // __webpack_public_path__ 81 | /******/ __webpack_require__.p = ""; 82 | /******/ 83 | /******/ 84 | /******/ // Load entry module and return exports 85 | /******/ return __webpack_require__(__webpack_require__.s = "./src/test.js"); 86 | /******/ }) 87 | /************************************************************************/ 88 | /******/ ({ 89 | 90 | /***/ "./src/test.js": 91 | /*!*********************!*\ 92 | !*** ./src/test.js ***! 93 | \*********************/ 94 | /*! no static exports found */ 95 | /***/ (function(module, exports) { 96 | 97 | eval("\r\nmodule.exports = 'hankewudi'\n\n//# sourceURL=webpack://ab/./src/test.js?"); 98 | 99 | /***/ }) 100 | 101 | /******/ }); -------------------------------------------------------------------------------- /webpack-go3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-go3", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack", 9 | "dev": "webpack-dev-server" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "@babel/core": "^7.4.5", 16 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 17 | "@babel/preset-env": "^7.4.5", 18 | "@babel/preset-react": "^7.0.0", 19 | "babel-loader": "^8.0.6", 20 | "happypack": "^5.0.1", 21 | "html-webpack-plugin": "^3.2.0", 22 | "webpack": "^4.33.0", 23 | "webpack-cli": "^3.3.2", 24 | "webpack-dev-server": "^3.7.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webpack-go3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /webpack-go3/src/a.js: -------------------------------------------------------------------------------- 1 | console.log('a') -------------------------------------------------------------------------------- /webpack-go3/src/b.js: -------------------------------------------------------------------------------- 1 | console.log('b') -------------------------------------------------------------------------------- /webpack-go3/src/index.js: -------------------------------------------------------------------------------- 1 | /* // import jquery from 'jquery' 2 | 3 | import moment from 'moment' 4 | 5 | //加入 ignorePlugin之后就不起作用了 6 | // moment.locale('zh-cn') 7 | 8 | //自己手动引入所需要的语言包 9 | import 'moment/locale/zh-cn' 10 | 11 | let r = moment().endOf('day').fromNow() 12 | 13 | console.log(r) */ 14 | 15 | /* import React from 'react' 16 | import {render} from 'react-dom' 17 | 18 | render( 19 |

jsx

, 20 | //这个默认的是那个root 21 | window.root 22 | ) */ 23 | 24 | /* import calc from './test' 25 | // import 在生产环境下会自动清除没用的东西 26 | // 相当于tree-shaking 没用代码自动删除 27 | // import 可以 但是 require就不行 28 | console.log(calc.sum(1,2)) 29 | // scope hosting 作用域提升 30 | // let a = 1 31 | // let b = 2 32 | // let c = 3 33 | // let d = a+b+c //webpack会自动省略可以简化的代码 34 | // console.log(d+'------') */ 35 | 36 | // import './a' 37 | // import './b' 38 | 39 | // console.log('index.js') 40 | 41 | /* let button = document.createElement('button') 42 | 43 | button.innerHTML = 'hello' 44 | 45 | //vue react懒加载 都是这样 46 | button.addEventListener('click',()=>{ 47 | //es6草案中的语法 实现jsonp动态加载文件 48 | import ('./source.js') .then(data=>{ 49 | console.log(data.default) 50 | }) 51 | }) 52 | 53 | document.body.append(button) */ 54 | 55 | import str from './source.js' 56 | 57 | console.log(str) 58 | 59 | if(module.hot) { 60 | module.hot.accept('./source.js',()=>{ 61 | //import只能写在页面的顶端 62 | let str =require('./source.js') 63 | console.log(str.default) 64 | }) 65 | } 66 | 67 | -------------------------------------------------------------------------------- /webpack-go3/src/other.js: -------------------------------------------------------------------------------- 1 | import './a' 2 | import './b' 3 | 4 | console.log('other.js') -------------------------------------------------------------------------------- /webpack-go3/src/source.js: -------------------------------------------------------------------------------- 1 | export default 'hanke234567' -------------------------------------------------------------------------------- /webpack-go3/src/test.js: -------------------------------------------------------------------------------- 1 | 2 | // module.exports = 'hankewudi' 3 | function sum(a,b) { 4 | return a+b 5 | } 6 | 7 | function mins(a,b) { 8 | return a-b 9 | } 10 | 11 | export default {sum,mins} -------------------------------------------------------------------------------- /webpack-go3/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | 4 | const HtmlWebpackPlugin = require('html-webpack-plugin') 5 | 6 | // 模块 happypack 来多线程打包webpack 进程(node中线程与进程关系) 打包文件会加快(文件很小时可能会变慢) 7 | // const Happypack = require('happypack') 8 | 9 | const htmlPlugin = new HtmlWebpackPlugin({ 10 | template: './public/index.html', 11 | 12 | }) 13 | 14 | //webpack自带的IgnorePlugin 忽略掉moment中locale引入的东西 15 | const ignorePlugin = new webpack.IgnorePlugin(/\.\/locale/,/moment/) 16 | 17 | //webpack自带的 动态引入链接库 18 | const dllReferencePlugin = new webpack.DllReferencePlugin({ 19 | manifest: path.resolve(__dirname,'dist','manifest.json') 20 | }) 21 | // happyplugin配置 22 | // const happyPlugin = new Happypack({ 23 | // id:'js', 24 | // use: [{ 25 | // loader:'babel-loader', 26 | // options: { 27 | // presets: [ 28 | // '@babel/preset-env', 29 | // '@babel/preset-react', 30 | // ] 31 | // } 32 | // }] 33 | // }) 34 | 35 | // 热更新所需插件 36 | const hotPlugin = new webpack.HotModuleReplacementPlugin() 37 | const namePlugin = new webpack.NamedModulesPlugin() //打印名字 38 | module.exports = { 39 | mode: "development", 40 | /* optimization: { 41 | splitChunks:{ //分割代码块 42 | cacheGrops:{ //缓存组 43 | common:{ //公共模块 44 | chunks: 'initial', //入口从哪找 45 | minSize: 0 , //大于0个字节 46 | minChunks: 0 //引用0次 47 | } 48 | }, 49 | vendor: { //抽离第三方模块 50 | priority: 1, //先抽离第三方模块 51 | test: /node_modules/, //引入 52 | chunks: 'initial', //入口从哪找 53 | minSize: 0 , //大于0个字节 54 | minChunks: 0 //引用0次 55 | } 56 | } 57 | }, */ 58 | entry: { 59 | index:'./src/index.js', 60 | //测试抽取公共代码用 61 | // other:'./src/other.js' 62 | }, 63 | output: { 64 | filename: 'index.js', 65 | path: path.resolve(__dirname,'dist'), 66 | }, 67 | //在package.json中配置 好像不起作用 不知道为啥子 不默认打开dist目录 先用这种方法吧 68 | devServer:{ 69 | //热更新 70 | hot: true, 71 | port: 3000, 72 | open: true, 73 | contentBase: './dist' 74 | }, 75 | plugins: [ 76 | htmlPlugin, 77 | //忽略插件 78 | ignorePlugin, 79 | //引入链接库插件 80 | dllReferencePlugin, 81 | //多线程打包文件 82 | // happyPlugin 83 | hotPlugin, 84 | namePlugin 85 | ], 86 | module:{ 87 | //不去解析jquery中的依赖库 88 | noParse: /jquery/, 89 | rules:[ 90 | { 91 | test: /\.js$/, 92 | //指定一个id 可能css也需要多线程打包 93 | // use: 'Happypack/loader?id=js', 94 | use: { 95 | loader:'babel-loader', 96 | options: { 97 | presets: [ 98 | '@babel/preset-env', 99 | '@babel/preset-react', 100 | ], 101 | plugins: [ 102 | '@babel/plugin-syntax-dynamic-import' 103 | ] 104 | } 105 | }, 106 | exclude: /node_modules/ 107 | } 108 | ] 109 | } 110 | 111 | } -------------------------------------------------------------------------------- /webpack-go3/webpack.react.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | 4 | //webpack自带插件 变成动态链接库 5 | const dllPlugin = new webpack.DllPlugin({ //name==library 6 | name: '_dll_[name]', 7 | //manifest.json就是一个任务清单 8 | path: path.resolve(__dirname,'dist','manifest.json') 9 | }) 10 | 11 | module.exports = { 12 | mode: 'development', 13 | entry: { 14 | // test: './src/test.js' 15 | react: ['react','react-dom'] 16 | }, 17 | output: { 18 | filename: '_dll_[name].js', //产生文件名 19 | path: path.resolve(__dirname,'dist'), 20 | //指定 var a = '...' 21 | library: '_dll_[name]', 22 | //配置commonjs 会变成export["ab"] 配置umd会变成umd模式 可配置 commonjs var this 主要用var(默认就是) 23 | //libraryTarget: 'var' 24 | }, 25 | plugins: [ 26 | //导出 manifest.json 以及 _dll_react.js 27 | dllPlugin 28 | ] 29 | } -------------------------------------------------------------------------------- /webpack-go4/async/AsyncPrallerHook(case).js: -------------------------------------------------------------------------------- 1 | class AsyncParallelHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | //实现tapPomise 6 | tapPromise(name,task) { 7 | this.tasks.push(task) 8 | } 9 | promise(...arg){ 10 | //用map映射 保存到tasks数组中 再使用Promise.all方法 全部运行后才执行 11 | let tasks = this.tasks.map(task=>task(...arg)) 12 | return Promise.all(tasks) 13 | } 14 | tapAsync(name,task) { 15 | this.tasks.push(task) 16 | } 17 | callAsync(...args) { 18 | let finalCallback = args.pop() 19 | let index = 0 20 | let done = ()=>{ 21 | index++ 22 | if(index===this.tasks.length){ 23 | finalCallback() 24 | } 25 | } 26 | this.tasks.forEach( task=>{ 27 | task(...args,done) 28 | }) 29 | } 30 | } 31 | let h = new AsyncParallelHook () 32 | /* h.tapAsync('node',(name,cb)=>{ 33 | setTimeout(()=>{ 34 | console.log('node',name) 35 | cb() 36 | },1000) 37 | }) 38 | h.tapAsync('react',(name,cb)=>{ 39 | setTimeout(()=>{ 40 | console.log('react',name) 41 | cb() 42 | },1000) 43 | }) 44 | h.callAsync('hanke',function(){ 45 | console.log('end') 46 | }) */ 47 | h.tapPromise('node',name=>{ 48 | return new Promise((resolve,reject)=>{ 49 | setTimeout(()=>{ 50 | console.log('node',name) 51 | resolve() 52 | },1000) 53 | }) 54 | }) 55 | h.tapPromise('react',name=>{ 56 | return new Promise((resolve,reject)=>{ 57 | setTimeout(()=>{ 58 | console.log('react',name) 59 | resolve() 60 | },1000) 61 | }) 62 | }) 63 | h.promise('hanke').then(()=>{ 64 | console.log('end') 65 | }) 66 | 67 | // AsyncParallelBailHook 带保险的异步并发操作 有reject()就不向下执行了 -------------------------------------------------------------------------------- /webpack-go4/async/AsyncPrallerHook.js: -------------------------------------------------------------------------------- 1 | let {AsyncParallelHook} = require('tapable') 2 | 3 | //异步的钩子 并行 等待所有并发的异步事件执行后再执行回调方法 4 | // 同时发送 多个请求 5 | 6 | //tapable有 注册分为三种方法 tap同步 tapAsync(cb) tapPromise(new Promise) 7 | // 调用也分为三种方法 call callAsync promise 8 | class lesson { 9 | constructor() { 10 | this.hooks = { 11 | arch: new AsyncParallelHook(['name']) 12 | } 13 | this.index = 0 14 | } 15 | //发布订阅的方式 这个得认真学一学 16 | /* 异步方法的第一种 tapAsync 17 | tap() { //注册 监听函数 18 | this.hooks.arch.tapAsync('node',(name,cb) => { 19 | setTimeout(()=>{ 20 | console.log('node',name) 21 | cb() 22 | },1000) 23 | }) 24 | this.hooks.arch.tapAsync('react',(name,cb) => { 25 | setTimeout(()=>{ 26 | console.log('react',name) 27 | cb() 28 | },1000) 29 | }) 30 | } 31 | start() { 32 | this.hooks.arch.callAsync('hanke',function(){ 33 | console.log("end") 34 | }) 35 | } */ 36 | tap() { 37 | this.hooks.arch.tapPromise('node',name => { 38 | return new Promise((resolve,reject)=>{ 39 | setTimeout(()=>{ 40 | console.log('node',name) 41 | resolve() 42 | },1000) 43 | }) 44 | 45 | }) 46 | this.hooks.arch.tapPromise('react',name => { 47 | return new Promise((resolve,reject)=>{ 48 | setTimeout(()=>{ 49 | console.log('react',name) 50 | resolve() 51 | },1000) 52 | }) 53 | }) 54 | } 55 | start() { 56 | this.hooks.arch.promise('hanke').then(function(){ 57 | console.log("end") 58 | }) 59 | } 60 | } 61 | 62 | let l = new lesson() 63 | l.tap() //注册这两个事件 64 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/async/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | class AsyncParallelHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | //实现tapPomise 6 | tapPromise(name,task) { 7 | this.tasks.push(task) 8 | } 9 | promise(...arg){ 10 | //用map映射 保存到tasks数组中 再使用Promise.all方法 全部运行后才执行 11 | let tasks = this.tasks.map(task=>task(...arg)) 12 | return Promise.all(tasks) 13 | } 14 | tapAsync(name,task) { 15 | this.tasks.push(task) 16 | } 17 | callAsync(...args) { 18 | let finalCallback = args.pop() 19 | let index = 0 20 | let done = ()=>{ 21 | index++ 22 | if(index===this.tasks.length){ 23 | finalCallback() 24 | } 25 | } 26 | this.tasks.forEach( task=>{ 27 | task(...args,done) 28 | }) 29 | } 30 | } 31 | let h = new AsyncParallelHook () 32 | /* h.tapAsync('node',(name,cb)=>{ 33 | setTimeout(()=>{ 34 | console.log('node',name) 35 | cb() 36 | },1000) 37 | }) 38 | h.tapAsync('react',(name,cb)=>{ 39 | setTimeout(()=>{ 40 | console.log('react',name) 41 | cb() 42 | },1000) 43 | }) 44 | h.callAsync('hanke',function(){ 45 | console.log('end') 46 | }) */ 47 | h.tapPromise('node',name=>{ 48 | return new Promise((resolve,reject)=>{ 49 | setTimeout(()=>{ 50 | console.log('node',name) 51 | resolve() 52 | },1000) 53 | }) 54 | }) 55 | h.tapPromise('react',name=>{ 56 | return new Promise((resolve,reject)=>{ 57 | setTimeout(()=>{ 58 | console.log('react',name) 59 | resolve() 60 | },1000) 61 | }) 62 | }) 63 | h.promise('hanke').then(()=>{ 64 | console.log('end') 65 | }) -------------------------------------------------------------------------------- /webpack-go4/asyncseries/AsyncSeriesHook(case).js: -------------------------------------------------------------------------------- 1 | class AsyncSeriesHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | //实现tapPomise 6 | tapPromise(name,task) { 7 | this.tasks.push(task) 8 | } 9 | promise(...arg){ 10 | //redux源码类似(还没开始学习呢) 真的太强了 我完全想不出来 11 | // 简直无敌啊 12 | let [first,...others] = this.tasks 13 | return others.reduce((promise,next)=>{ 14 | return promise.then(()=> next(...arg)) 15 | },first(...arg)) 16 | } 17 | tapAsync(name,task) { 18 | this.tasks.push(task) 19 | } 20 | callAsync(...args) { 21 | let finalCallback = args.pop() 22 | let index = 0 23 | let next = () => { 24 | if(index === this.tasks.length) return finalCallback() 25 | let task = this.tasks[index++] 26 | task(...args,next) 27 | } 28 | next() 29 | } 30 | } 31 | let h = new AsyncSeriesHook () 32 | /* h.tapAsync('node',(name,cb)=>{ 33 | setTimeout(()=>{ 34 | console.log('node',name) 35 | //cb()对应着 next 36 | cb() 37 | },1000) 38 | }) 39 | h.tapAsync('react',(name,cb)=>{ 40 | setTimeout(()=>{ 41 | console.log('react',name) 42 | cb() 43 | },1000) 44 | }) 45 | h.callAsync('hanke',function(){ 46 | console.log('end') 47 | }) */ 48 | h.tapPromise('node',name=>{ 49 | return new Promise((resolve,reject)=>{ 50 | setTimeout(()=>{ 51 | console.log('node',name) 52 | resolve() 53 | },1000) 54 | }) 55 | }) 56 | h.tapPromise('react',name=>{ 57 | return new Promise((resolve,reject)=>{ 58 | setTimeout(()=>{ 59 | console.log('react',name) 60 | resolve() 61 | },1000) 62 | }) 63 | }) 64 | h.promise('hanke').then(()=>{ 65 | console.log('end') 66 | }) -------------------------------------------------------------------------------- /webpack-go4/asyncseries/AsyncSeriesHook.js: -------------------------------------------------------------------------------- 1 | let {AsyncSeriesHook} = require('tapable') 2 | 3 | // 异步串行 先执行完一个再执行下一个 类似于express中间件 先执行完才可以再执行0 4 | // tapAsync tapPromise都可以 5 | class lesson { 6 | constructor() { 7 | this.hooks = { 8 | arch: new AsyncSeriesHook(['name']) 9 | } 10 | this.index = 0 11 | } 12 | //发布订阅的方式 这个得认真学一学 13 | //异步方法的第一种 tapAsync 14 | /* tap() { //注册 监听函数 15 | this.hooks.arch.tapAsync('node',(name,cb) => { 16 | setTimeout(()=>{ 17 | console.log('node',name) 18 | cb() 19 | },1000) 20 | }) 21 | this.hooks.arch.tapAsync('react',(name,cb) => { 22 | setTimeout(()=>{ 23 | console.log('react',name) 24 | cb() 25 | },1000) 26 | }) 27 | } 28 | start() { 29 | this.hooks.arch.callAsync('hanke',function(){ 30 | console.log("end") 31 | }) 32 | } */ 33 | tap() { 34 | this.hooks.arch.tapPromise('node',name => { 35 | return new Promise((resolve,reject)=>{ 36 | setTimeout(()=>{ 37 | console.log('node',name) 38 | resolve() 39 | },1000) 40 | }) 41 | 42 | }) 43 | this.hooks.arch.tapPromise('react',name => { 44 | return new Promise((resolve,reject)=>{ 45 | setTimeout(()=>{ 46 | console.log('react',name) 47 | resolve() 48 | },1000) 49 | }) 50 | }) 51 | } 52 | start() { 53 | this.hooks.arch.promise('hanke').then(function(){ 54 | console.log("end") 55 | }) 56 | } 57 | } 58 | 59 | let l = new lesson() 60 | l.tap() //注册这两个事件 61 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/asyncseries/AsyncSeriesWaterfall(case).js: -------------------------------------------------------------------------------- 1 | class AsyncSeriesWaterfallHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | //实现tapPomise 6 | tapPromise(name,task) { 7 | this.tasks.push(task) 8 | } 9 | promise(...arg){ 10 | //redux源码类似(还没开始学习呢) 真的太强了 我完全想不出来 11 | // 简直无敌啊 12 | let [first,...others] = this.tasks 13 | return others.reduce((promise,next)=>{ 14 | return promise.then(data=> { 15 | if(data===undefined) { 16 | return next(...arg) 17 | } 18 | else { 19 | return next(data) 20 | } 21 | }) 22 | },first(...arg)) 23 | } 24 | tapAsync(name,task) { 25 | this.tasks.push(task) 26 | } 27 | callAsync(...args) { 28 | let finalCallback = args.pop() 29 | let index = 0 30 | let next = (err,data) => { 31 | let task = this.tasks[index] 32 | if(!task || err==='error'){ 33 | return finalCallback() 34 | }else { 35 | if(index===0) { 36 | task(...args,next) 37 | }else { 38 | if(data===undefined){ 39 | task(...args,next) 40 | } else { 41 | task(data,next) 42 | } 43 | } 44 | } 45 | index++ 46 | } 47 | next() 48 | } 49 | } 50 | let h = new AsyncSeriesWaterfallHook () 51 | /* h.tapAsync('node',(name,cb)=>{ 52 | setTimeout(()=>{ 53 | console.log('node',name) 54 | //cb()对应着 next 55 | cb(null,'结果') 56 | },1000) 57 | }) 58 | h.tapAsync('react',(name,cb)=>{ 59 | setTimeout(()=>{ 60 | console.log('react',name) 61 | cb() 62 | },1000) 63 | }) 64 | h.callAsync('hanke',function(){ 65 | console.log('end') 66 | }) */ 67 | h.tapPromise('node',name=>{ 68 | return new Promise((resolve,reject)=>{ 69 | setTimeout(()=>{ 70 | console.log('node',name) 71 | resolve() 72 | },1000) 73 | }) 74 | }) 75 | h.tapPromise('react',name=>{ 76 | return new Promise((resolve,reject)=>{ 77 | setTimeout(()=>{ 78 | console.log('react',name) 79 | resolve() 80 | },1000) 81 | }) 82 | }) 83 | h.promise('hanke').then(()=>{ 84 | console.log('end') 85 | }) -------------------------------------------------------------------------------- /webpack-go4/asyncseries/AsyncSeriesWaterfall.js: -------------------------------------------------------------------------------- 1 | let {AsyncSeriesWaterfallHook} = require('tapable') 2 | 3 | // 异步串行 先执行完一个再执行下一个 类似于express中间件 先执行完才可以再执行0 4 | // tapAsync tapPromise都可以 5 | class lesson { 6 | constructor() { 7 | this.hooks = { 8 | arch: new AsyncSeriesWaterfallHook(['name']) 9 | } 10 | this.index = 0 11 | } 12 | //发布订阅的方式 这个得认真学一学 13 | //异步方法的第一种 tapAsync 14 | /* tap() { //注册 监听函数 15 | this.hooks.arch.tapAsync('node',(name,cb) => { 16 | setTimeout(()=>{ 17 | console.log('node',name) 18 | cb() 19 | },1000) 20 | }) 21 | this.hooks.arch.tapAsync('react',(name,cb) => { 22 | setTimeout(()=>{ 23 | console.log('react',name) 24 | cb() 25 | },1000) 26 | }) 27 | } 28 | start() { 29 | this.hooks.arch.callAsync('hanke',function(){ 30 | console.log("end") 31 | }) 32 | } */ 33 | tap() { 34 | this.hooks.arch.tapPromise('node',name => { 35 | return new Promise((resolve,reject)=>{ 36 | setTimeout(()=>{ 37 | console.log('node',name) 38 | resolve('err') 39 | },1000) 40 | }) 41 | 42 | }) 43 | this.hooks.arch.tapPromise('react',name => { 44 | return new Promise((resolve,reject)=>{ 45 | setTimeout(()=>{ 46 | console.log('react',name) 47 | resolve() 48 | },1000) 49 | }) 50 | }) 51 | } 52 | start() { 53 | this.hooks.arch.promise('hanke').then(function(){ 54 | console.log("end") 55 | }) 56 | } 57 | } 58 | 59 | let l = new lesson() 60 | l.tap() //注册这两个事件 61 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/asyncseries/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | class AsyncSeriesWaterfallHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | //实现tapPomise 6 | tapPromise(name,task) { 7 | this.tasks.push(task) 8 | } 9 | promise(...arg){ 10 | //redux源码类似(还没开始学习呢) 真的太强了 我完全想不出来 11 | // 简直无敌啊 12 | let [first,...others] = this.tasks 13 | return others.reduce((promise,next)=>{ 14 | return promise.then((err,data)=> next(data)) 15 | },first(...arg)) 16 | } 17 | tapAsync(name,task) { 18 | this.tasks.push(task) 19 | } 20 | callAsync(...args) { 21 | let finalCallback = args.pop() 22 | let index = 0 23 | let next = (err,data) => { 24 | let task = this.tasks[index] 25 | if(!task || err==='error'){ 26 | return finalCallback() 27 | }else { 28 | if(index===0) { 29 | task(...args,next) 30 | }else { 31 | if(data===undefined){ 32 | task(...args,next) 33 | } else { 34 | task(data,next) 35 | } 36 | } 37 | } 38 | index++ 39 | } 40 | next() 41 | } 42 | } 43 | let h = new AsyncSeriesWaterfallHook () 44 | /* h.tapAsync('node',(name,cb)=>{ 45 | setTimeout(()=>{ 46 | console.log('node',name) 47 | //cb()对应着 next 48 | cb(null,'结果') 49 | },1000) 50 | }) 51 | h.tapAsync('react',(name,cb)=>{ 52 | setTimeout(()=>{ 53 | console.log('react',name) 54 | cb() 55 | },1000) 56 | }) 57 | h.callAsync('hanke',function(){ 58 | console.log('end') 59 | }) */ 60 | h.tapPromise('node',name=>{ 61 | return new Promise((resolve,reject)=>{ 62 | setTimeout(()=>{ 63 | console.log('node',name) 64 | resolve(null,'结果') 65 | },1000) 66 | }) 67 | }) 68 | h.tapPromise('react',name=>{ 69 | return new Promise((resolve,reject)=>{ 70 | setTimeout(()=>{ 71 | console.log('react',name) 72 | resolve() 73 | },1000) 74 | }) 75 | }) 76 | h.promise('hanke').then(()=>{ 77 | console.log('end') 78 | }) -------------------------------------------------------------------------------- /webpack-go4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-go4", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "dependencies": { 7 | "_tapable@1.1.3@tapable": "^1.1.3", 8 | "tapable": "^1.1.3" 9 | }, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC" 17 | } 18 | -------------------------------------------------------------------------------- /webpack-go4/sync/case(SyncBailHook).js: -------------------------------------------------------------------------------- 1 | // SyncHook的实现 2 | class SyncBailHook { 3 | constructor(args) { 4 | this.tasks = [] 5 | } 6 | tap(name,task) { 7 | this.tasks.push(task) 8 | } 9 | call(...args) { 10 | // this.tasks.map(task=>task(...args)) 11 | let ret,index=0 12 | do{ 13 | ret = this.tasks[index++](...args) 14 | }while(ret === undefined && index < this.tasks.length) 15 | } 16 | } 17 | let h = new SyncBailHook() 18 | h.tap('node',(name)=>{ 19 | console.log('node',name) 20 | return '停一停吧' 21 | }) 22 | h.tap('react',(name)=>{ 23 | console.log('react',name) 24 | }) 25 | h.call('hanke') -------------------------------------------------------------------------------- /webpack-go4/sync/case(SyncHook).js: -------------------------------------------------------------------------------- 1 | // SyncHook的实现 2 | class SyncHook { 3 | constructor(args) { 4 | this.tasks = [] 5 | } 6 | tap(name,task) { 7 | this.tasks.push(task) 8 | } 9 | call(...args) { 10 | this.tasks.map(task=>task(...args)) 11 | } 12 | } 13 | let h = new SyncHook() 14 | h.tap('node',(name)=>{ 15 | console.log('node',name) 16 | }) 17 | h.tap('react',(name)=>{ 18 | console.log('react',name) 19 | }) 20 | h.call('hanke') -------------------------------------------------------------------------------- /webpack-go4/sync/case(SyncLoopHook).js: -------------------------------------------------------------------------------- 1 | class SyncLoopHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | tap(name,task) { 6 | this.tasks.push(task) 7 | } 8 | call(...args) { 9 | // this.tasks.map(task=>task(...args)) 10 | let ret 11 | this.tasks.forEach(task=>{ 12 | do{ 13 | ret = task(...args) 14 | }while(ret!=undefined) 15 | }) 16 | } 17 | } 18 | let h = new SyncLoopHook () 19 | let total = 0 20 | h.tap('node',(name)=>{ 21 | console.log('node',name) 22 | return ++total === 3? undefined:'继续' 23 | }) 24 | h.tap('react',(name)=>{ 25 | console.log('react',name) 26 | }) 27 | h.call('hanke') -------------------------------------------------------------------------------- /webpack-go4/sync/case(SyncWaterfallHook).js: -------------------------------------------------------------------------------- 1 | // SyncHook的实现 2 | class SyncWaterfallHook { 3 | constructor(args) { 4 | this.tasks = [] 5 | } 6 | tap(name,task) { 7 | this.tasks.push(task) 8 | } 9 | call(...args) { 10 | // this.tasks.map(task=>task(...args)) 11 | /* let ret,index=0 12 | ret = this.tasks[index++](...args) 13 | while(index b(a),ret) 24 | } 25 | } 26 | let h = new SyncWaterfallHook() 27 | h.tap('node',(name)=>{ 28 | console.log('node',name) 29 | return 'node ok' 30 | }) 31 | h.tap('react',(data)=>{ 32 | console.log('react',data) 33 | return 'react ok' 34 | }) 35 | h.tap('webpack',(data)=>{ 36 | console.log('webpack',data) 37 | }) 38 | h.call('hanke') -------------------------------------------------------------------------------- /webpack-go4/sync/start(SyncBailHook).js: -------------------------------------------------------------------------------- 1 | let {SyncBailHook} = require('tapable') 2 | 3 | class lesson { 4 | constructor() { 5 | this.hooks = { 6 | arch: new SyncBailHook(['name']) 7 | } 8 | } 9 | //发布订阅的方式 这个得认真学一学 10 | tap() { //注册 监听函数 11 | this.hooks.arch.tap('node',function(name){ 12 | console.log('node',name) 13 | //SyncBailHook可以卡住 return不是一个undefined的值就不会向下执行 14 | return '不太会,等一等' 15 | }) 16 | this.hooks.arch.tap('react',function(name){ 17 | console.log('react',name) 18 | }) 19 | } 20 | start() { 21 | this.hooks.arch.call('hanke') 22 | } 23 | } 24 | 25 | let l = new lesson() 26 | l.tap() //注册这两个事件 27 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/sync/start(SyncHook).js: -------------------------------------------------------------------------------- 1 | let {SyncHook} = require('tapable') 2 | 3 | class lesson { 4 | constructor() { 5 | this.hooks = { 6 | arch: new SyncHook(['name']) 7 | } 8 | } 9 | //发布订阅的方式 这个得认真学一学 10 | tap() { //注册 监听函数 11 | this.hooks.arch.tap('node',function(name){ 12 | console.log('node',name) 13 | }) 14 | this.hooks.arch.tap('react',function(name){ 15 | console.log('react',name) 16 | }) 17 | } 18 | start() { 19 | this.hooks.arch.call('hanke') 20 | } 21 | } 22 | 23 | let l = new lesson() 24 | l.tap() //注册这两个事件 25 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/sync/start(SyncLoopHook).1.js: -------------------------------------------------------------------------------- 1 | let {SyncLoopHook} = require('tapable') 2 | 3 | //同步遇到某个不返回undefined的值会多次执行 4 | class lesson { 5 | constructor() { 6 | this.hooks = { 7 | arch: new SyncLoopHook(['name']) 8 | } 9 | this.index = 0 10 | } 11 | //发布订阅的方式 这个得认真学一学 12 | tap() { //注册 监听函数 13 | this.hooks.arch.tap('node',(name) => { 14 | console.log('node',name) 15 | //SyncBailHook可以卡住 return不是一个undefined的值就不会向下执行 16 | // return '不太会,等一等' 17 | return ++this.index === 3 ? undefined:'继续' 18 | }) 19 | this.hooks.arch.tap('react',(name) => { 20 | console.log('react',name) 21 | }) 22 | } 23 | start() { 24 | this.hooks.arch.call('hanke') 25 | } 26 | } 27 | 28 | let l = new lesson() 29 | l.tap() //注册这两个事件 30 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/sync/start(SyncWaterfallHook).js: -------------------------------------------------------------------------------- 1 | let {SyncWaterfallHook} = require('tapable') 2 | 3 | class lesson { 4 | constructor() { 5 | this.hooks = { 6 | arch: new SyncWaterfallHook(['name']) 7 | } 8 | } 9 | //发布订阅的方式 这个得认真学一学 10 | tap() { //注册 监听函数 11 | this.hooks.arch.tap('node',function(name){ 12 | console.log('node',name) 13 | // return 'node还行' 14 | // waterfull 返回值会传给下一个 15 | }) 16 | this.hooks.arch.tap('react',function(name){ 17 | console.log('react',name) 18 | }) 19 | this.hooks.arch.tap('react',function(name){ 20 | console.log('react',name) 21 | }) 22 | } 23 | start() { 24 | this.hooks.arch.call('hanke') 25 | } 26 | } 27 | 28 | let l = new lesson() 29 | l.tap() //注册这两个事件 30 | l.start() //启动钩子函数 -------------------------------------------------------------------------------- /webpack-go4/sync/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | class SyncLoopHook { 2 | constructor(args) { 3 | this.tasks = [] 4 | } 5 | tap(name,task) { 6 | this.tasks.push(task) 7 | } 8 | call(...args) { 9 | // this.tasks.map(task=>task(...args)) 10 | let ret 11 | this.tasks.forEach(task=>{ 12 | do{ 13 | ret = task(...args) 14 | }while(ret!=undefined) 15 | }) 16 | } 17 | } 18 | let h = new SyncLoopHook () 19 | let total = 0 20 | h.tap('node',(name)=>{ 21 | console.log('node',name) 22 | return ++total === 3? undefined:'继续' 23 | }) 24 | h.tap('react',(name)=>{ 25 | console.log('react',name) 26 | }) 27 | h.call('hanke') -------------------------------------------------------------------------------- /webpack-go4/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | // SyncHook的实现 2 | class SyncBailHook { 3 | constructor(args) { 4 | this.tasks = [] 5 | } 6 | tap(name,task) { 7 | this.tasks.push(task) 8 | } 9 | call(...args) { 10 | // this.tasks.map(task=>task(...args)) 11 | let ret,index=0 12 | do{ 13 | ret = this.tasks[index++](...args) 14 | }while(ret === undefined && index < this.tasks.length) 15 | } 16 | } 17 | let h = new SyncBailHook() 18 | h.tap('node',(name)=>{ 19 | console.log('node',name) 20 | // return '停一停吧' 21 | }) 22 | h.tap('react',(name)=>{ 23 | console.log('react',name) 24 | }) 25 | h.call('hanke') -------------------------------------------------------------------------------- /webpack-go5/dist/bundle.js: -------------------------------------------------------------------------------- 1 | (function(modules) { // webpackBootstrap webpack入口函数 2 | var installedModules = {}; 3 | function __webpack_require__(moduleId) { 4 | if(installedModules[moduleId]) { 5 | return installedModules[moduleId].exports; 6 | } 7 | var module = installedModules[moduleId] = { 8 | i: moduleId, 9 | l: false, 10 | exports: {} 11 | }; 12 | modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 13 | return module.exports; 14 | } 15 | return __webpack_require__(__webpack_require__.s = "./src\index.js");//入口模块 16 | }) 17 | 18 | ({ 19 | 20 | "./src\index.js": //key->模块的路径 21 | (function(module, exports,__webpack_require__) { 22 | eval(`let str = __webpack_require__("./src\\a.js"); 23 | 24 | __webpack_require__("./src\\index.less"); 25 | 26 | console.log(str);`); 27 | }), 28 | 29 | "./src\a.js": //key->模块的路径 30 | (function(module, exports,__webpack_require__) { 31 | eval(`let b = __webpack_require__("./src\\base\\b.js"); 32 | 33 | module.exports = 'a' + b;`); 34 | }), 35 | 36 | "./src\base\b.js": //key->模块的路径 37 | (function(module, exports,__webpack_require__) { 38 | eval(`module.exports = 'b';`); 39 | }), 40 | 41 | "./src\index.less": //key->模块的路径 42 | (function(module, exports,__webpack_require__) { 43 | eval(`let style = document.createElement('style'); 44 | style.innerHTML = "body {\\n background-color: red;\\n}\\n"; 45 | document.head.appendChild(style);`); 46 | }), 47 | 48 | 49 | }); -------------------------------------------------------------------------------- /webpack-go5/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webpack-go5/dist/main.js: -------------------------------------------------------------------------------- 1 | (function(modules) { 2 | 3 | var installedModules = {}; 4 | 5 | 6 | function __webpack_require__(moduleId) { 7 | 8 | if(installedModules[moduleId]) { 9 | return installedModules[moduleId].exports; 10 | } 11 | var module = installedModules[moduleId] = { 12 | i: moduleId, 13 | l: false, 14 | exports: {} 15 | }; 16 | modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 17 | return module.exports; 18 | } 19 | 20 | return __webpack_require__(__webpack_require__.s = "./src/index.js"); 21 | }) 22 | ({ 23 | 24 | "./src/a.js": 25 | (function(module, exports, __webpack_require__) { 26 | 27 | eval("let b = __webpack_require__(/*! ./base/b.js */ \"./src/base/b.js\")\r\nmodule.exports = 'a' + b\n\n//# sourceURL=webpack:///./src/a.js?"); 28 | 29 | }), 30 | 31 | "./src/base/b.js": 32 | 33 | (function(module, exports) { 34 | 35 | eval("module.exports = 'b'\n\n//# sourceURL=webpack:///./src/base/b.js?"); 36 | 37 | }), 38 | 39 | "./src/index.js": 40 | 41 | (function(module, exports, __webpack_require__) { 42 | 43 | eval("let str = __webpack_require__(/*! ./a.js */ \"./src/a.js\")\r\nconsole.log(str)\n\n//# sourceURL=webpack:///./src/index.js?"); 44 | 45 | }) 46 | 47 | }); -------------------------------------------------------------------------------- /webpack-go5/dist/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | (function(modules) { // webpackBootstrap webpack入口函数 2 | var installedModules = {}; 3 | function __webpack_require__(moduleId) { 4 | if(installedModules[moduleId]) { 5 | return installedModules[moduleId].exports; 6 | } 7 | modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 8 | return module.exports; 9 | } 10 | return __webpack_require__(__webpack_require__.s = "./src\index.js");//入口模块 11 | }) 12 | 13 | ({ 14 | 15 | "./src\index.js": //key->模块的路径 16 | (function(module, exports,__webpack_require__) { 17 | eval(`let str = __webpack_require__("./src\\a.js"); 18 | 19 | console.log(str);`); 20 | }), 21 | 22 | "./src\a.js": //key->模块的路径 23 | (function(module, exports,__webpack_require__) { 24 | eval(`let b = __webpack_require__("./src\\base\\b.js"); 25 | 26 | module.exports = 'a' + b;`); 27 | }), 28 | 29 | "./src\base\b.js": //key->模块的路径 30 | (function(module, exports,__webpack_require__) { 31 | eval(`module.exports = 'b';`); 32 | }), 33 | 34 | 35 | }); -------------------------------------------------------------------------------- /webpack-go5/loader/less-loader.js: -------------------------------------------------------------------------------- 1 | let less = require('less') 2 | let css = '' 3 | function loader(source){ 4 | less.render(source,(error,c)=>{ 5 | css = c.css 6 | }) 7 | //正则 将/n替换成//n 不然会被当做转义字符来处理 不换行 8 | css = css.replace(/\n/g,'\\n') 9 | return css 10 | } 11 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go5/loader/style-loader.js: -------------------------------------------------------------------------------- 1 | let style = '' 2 | function loader(source){ 3 | style = `let style = document.createElement('style') 4 | style.innerHTML = ${JSON.stringify(source)} 5 | document.head.appendChild(style)` 6 | return style 7 | 8 | //style.innerHTML = JSON.stringify(loader) 可以将index.less的代码转为一行 9 | } 10 | 11 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-go5", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babylon": "^6.18.0", 14 | "webpack": "^4.33.0", 15 | "webpack-cli": "^3.3.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /webpack-go5/src/a.js: -------------------------------------------------------------------------------- 1 | let b = require('./base/b.js') 2 | module.exports = 'a' + b -------------------------------------------------------------------------------- /webpack-go5/src/base/b.js: -------------------------------------------------------------------------------- 1 | module.exports = 'b' -------------------------------------------------------------------------------- /webpack-go5/src/index.js: -------------------------------------------------------------------------------- 1 | let str = require('./a.js') 2 | require('./index.less') 3 | console.log(str) -------------------------------------------------------------------------------- /webpack-go5/src/index.less: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: red; 3 | } -------------------------------------------------------------------------------- /webpack-go5/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | //模拟插件 3 | class P{ 4 | apply(compiler){ 5 | //发射 订阅 6 | compiler.hooks.emit.tap('emit',()=>{ 7 | console.log('emit事件') 8 | }) 9 | } 10 | } 11 | class P1{ 12 | apply(compiler){ 13 | //发射 订阅 14 | compiler.hooks.afterPlugins.tap('emit',()=>{ 15 | console.log('afterPlugins') 16 | }) 17 | } 18 | } 19 | module.exports = { 20 | mode: 'development', 21 | entry: './src/index.js', 22 | output:{ 23 | filename: 'bundle.js', 24 | path: path.resolve(__dirname,'dist') 25 | }, 26 | module:{ 27 | rules:[ 28 | { 29 | test: /\.less$/, 30 | use:[ 31 | path.resolve(__dirname,'loader','style-loader'), 32 | path.resolve(__dirname,'loader','less-loader') 33 | ] 34 | } 35 | ] 36 | }, 37 | plugins:[ 38 | new P(), 39 | new P1() 40 | ] 41 | } -------------------------------------------------------------------------------- /webpack-go6/banner.js: -------------------------------------------------------------------------------- 1 | hankegogogo111 -------------------------------------------------------------------------------- /webpack-go6/dist/9457fbc2cf600903b9863a416cb4b7f4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1better/mywebpack/d321b5393ca9d6405fcceceee4e09ada9ec696a3/webpack-go6/dist/9457fbc2cf600903b9863a416cb4b7f4.jpg -------------------------------------------------------------------------------- /webpack-go6/dist/build.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | /******/ 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | /******/ 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) { 10 | /******/ return installedModules[moduleId].exports; 11 | /******/ } 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ i: moduleId, 15 | /******/ l: false, 16 | /******/ exports: {} 17 | /******/ }; 18 | /******/ 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | /******/ 22 | /******/ // Flag the module as loaded 23 | /******/ module.l = true; 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | /******/ 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | /******/ 36 | /******/ // define getter function for harmony exports 37 | /******/ __webpack_require__.d = function(exports, name, getter) { 38 | /******/ if(!__webpack_require__.o(exports, name)) { 39 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 | /******/ } 41 | /******/ }; 42 | /******/ 43 | /******/ // define __esModule on exports 44 | /******/ __webpack_require__.r = function(exports) { 45 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 | /******/ } 48 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49 | /******/ }; 50 | /******/ 51 | /******/ // create a fake namespace object 52 | /******/ // mode & 1: value is a module id, require it 53 | /******/ // mode & 2: merge all properties of value into the ns 54 | /******/ // mode & 4: return value when already ns object 55 | /******/ // mode & 8|1: behave like require 56 | /******/ __webpack_require__.t = function(value, mode) { 57 | /******/ if(mode & 1) value = __webpack_require__(value); 58 | /******/ if(mode & 8) return value; 59 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 | /******/ var ns = Object.create(null); 61 | /******/ __webpack_require__.r(ns); 62 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 | /******/ return ns; 65 | /******/ }; 66 | /******/ 67 | /******/ // getDefaultExport function for compatibility with non-harmony modules 68 | /******/ __webpack_require__.n = function(module) { 69 | /******/ var getter = module && module.__esModule ? 70 | /******/ function getDefault() { return module['default']; } : 71 | /******/ function getModuleExports() { return module; }; 72 | /******/ __webpack_require__.d(getter, 'a', getter); 73 | /******/ return getter; 74 | /******/ }; 75 | /******/ 76 | /******/ // Object.prototype.hasOwnProperty.call 77 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78 | /******/ 79 | /******/ // __webpack_public_path__ 80 | /******/ __webpack_require__.p = ""; 81 | /******/ 82 | /******/ 83 | /******/ // Load entry module and return exports 84 | /******/ return __webpack_require__(__webpack_require__.s = "./src/index.js"); 85 | /******/ }) 86 | /************************************************************************/ 87 | /******/ ({ 88 | 89 | /***/ "./loader/css-loader.js!./loader/less-loader.js!./src/index.less": 90 | /*!***********************************************************************!*\ 91 | !*** ./loader/css-loader.js!./loader/less-loader.js!./src/index.less ***! 92 | \***********************************************************************/ 93 | /*! no static exports found */ 94 | /***/ (function(module, exports, __webpack_require__) { 95 | 96 | let list = [] 97 | list.push("body {\n background: ") 98 | list.push('url('+ __webpack_require__(/*! ./lala.jpg */ "./src/lala.jpg") +')') 99 | list.push(" no-repeat;\n}\n") 100 | module.exports = list.join(' ') 101 | 102 | /***/ }), 103 | 104 | /***/ "./src/index.js": 105 | /*!**********************!*\ 106 | !*** ./src/index.js ***! 107 | \**********************/ 108 | /*! no static exports found */ 109 | /***/ (function(module, exports, __webpack_require__) { 110 | 111 | // console.log('hello') 112 | 113 | //inline-loader! 这样会运行inline-loader 114 | // -!不会通过 pre normal来处理了 115 | // !没有normal 116 | // !!什么都不要 只用inline-loader 117 | // require('inline-loader!./a.js') 118 | 119 | /* class Hanke{ 120 | constructor(){ 121 | this.name = 'hanke' 122 | } 123 | getName(){ 124 | return this.name 125 | } 126 | } 127 | var h = new Hanke() 128 | console.log(h.getName()) */ 129 | 130 | /* import p from './lala.jpg' 131 | console.log(p) 132 | let img = document.createElement('img') 133 | img.src = p 134 | document.body.appendChild(img) */ 135 | 136 | __webpack_require__(/*! ./index.less */ "./src/index.less") 137 | 138 | /***/ }), 139 | 140 | /***/ "./src/index.less": 141 | /*!************************!*\ 142 | !*** ./src/index.less ***! 143 | \************************/ 144 | /*! no static exports found */ 145 | /***/ (function(module, exports, __webpack_require__) { 146 | 147 | style = document.createElement('style') 148 | style.innerHTML = __webpack_require__(/*! !../loader/css-loader.js!../loader/less-loader.js!./index.less */ "./loader/css-loader.js!./loader/less-loader.js!./src/index.less") 149 | document.head.appendChild(style) 150 | 151 | /***/ }), 152 | 153 | /***/ "./src/lala.jpg": 154 | /*!**********************!*\ 155 | !*** ./src/lala.jpg ***! 156 | \**********************/ 157 | /*! no static exports found */ 158 | /***/ (function(module, exports) { 159 | 160 | module.exports = "data:image/jpeg;base64,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" 161 | 162 | /***/ }) 163 | 164 | /******/ }); 165 | //# sourceMappingURL=build.js.map -------------------------------------------------------------------------------- /webpack-go6/dist/build.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.less","webpack:///./src/index.js","webpack:///./src/index.less?4421","webpack:///./src/lala.jpg"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,kDAA0C,gCAAgC;AAC1E;AACA;;AAEA;AACA;AACA;AACA,gEAAwD,kBAAkB;AAC1E;AACA,yDAAiD,cAAc;AAC/D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAyC,iCAAiC;AAC1E,wHAAgH,mBAAmB,EAAE;AACrI;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;;AAGA;AACA;;;;;;;;;;;;AClFA;AACA,iBAAiB;AACjB,kBAAkB,mBAAO,CAAC,kCAAY;AACtC,sBAAsB,GAAG;AACzB,+B;;;;;;;;;;;ACJA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,mBAAO,CAAC,sCAAc,C;;;;;;;;;;;ACzBtB;AACA,oBAAoB,mBAAO,CAAC,uIAAiE;AAC7F,kC;;;;;;;;;;;ACFA,kCAAkC,wwJ","file":"build.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/index.js\");\n","let list = []\r\nlist.push(\"body {\\n background: \")\r\nlist.push('url('+ require('./lala.jpg') +')')\r\nlist.push(\" no-repeat;\\n}\\n\")\r\nmodule.exports = list.join(' ')","// console.log('hello')\r\n\r\n//inline-loader! 这样会运行inline-loader\r\n// -!不会通过 pre normal来处理了\r\n// !没有normal\r\n// !!什么都不要 只用inline-loader\r\n// require('inline-loader!./a.js')\r\n\r\n/* class Hanke{\r\n constructor(){\r\n this.name = 'hanke'\r\n }\r\n getName(){\r\n return this.name\r\n }\r\n}\r\nvar h = new Hanke()\r\nconsole.log(h.getName()) */\r\n\r\n/* import p from './lala.jpg'\r\nconsole.log(p)\r\nlet img = document.createElement('img')\r\nimg.src = p\r\ndocument.body.appendChild(img) */\r\n\r\nrequire('./index.less')","style = document.createElement('style')\n style.innerHTML = require(\"!!../loader/css-loader.js!../loader/less-loader.js!./index.less\")\n document.head.appendChild(style)","module.exports = \"data:image/jpeg;base64,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\""],"sourceRoot":""} -------------------------------------------------------------------------------- /webpack-go6/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webpack-go6/loader/babel-loader.js: -------------------------------------------------------------------------------- 1 | let babel = require("@babel/core"); 2 | //loaderUtils 拿到预设 便于后期转化代码 3 | let loaderUtils = require("loader-utils"); 4 | function loader(source) { // this loaderContext 5 | //Object.keys方法 属性转成一个数组 6 | let options = loaderUtils.getOptions(this); 7 | // console.log(this.resourcePath) 运行时返回一个绝对路径 8 | //console.log(options); 9 | // options 打印为{ presets: [ '@babel/preset-env' ] } 10 | let cb = this.async() // loader上下文 默认有async这个方法 异步执行 在哪执行调用cb就可以 11 | //babel的transform有三个参数 第一个 转换哪些代码 第二个 转换选项 第三个 异步回调函数 12 | babel.transform(source,{ 13 | ...options, //对象展开 14 | sourceMap: true, //调试工具 需要webpack.config.js 也要配置 source-map 15 | filename: this.resourcePath.split('/').pop()//文件名 不然运行时 webpack下边是unkown 16 | 17 | },function(err,result){ 18 | //异步回调 return source就不起作用了 19 | cb(err,result.code,result.map) // 异步 cb(123) 会错误 必须严格按照参数来 20 | // 第一个 错误 第二个 代码 第三个 sourceMap 21 | }) 22 | // return source; 不起作用 23 | } 24 | module.exports = loader; 25 | -------------------------------------------------------------------------------- /webpack-go6/loader/banner-loader.js: -------------------------------------------------------------------------------- 1 | let loaderUtils = require('loader-utils') 2 | //骨架校验 3 | let validateOptions = require('schema-utils') 4 | //读取文件模块 5 | let fs = require('fs') 6 | function loader(source){ 7 | this.cacheable && this.cacheable() //一般这样用 8 | //this.cacheable(false) //缓存 自动缓存 9 | let options = loaderUtils.getOptions(this) 10 | let cb = this.async() //异步必备 11 | let schema = { 12 | type: 'object', 13 | properties: { 14 | text: { 15 | type: 'string', 16 | 17 | }, 18 | filename: { 19 | type: 'string' 20 | } 21 | } 22 | } 23 | //将骨架和参数对比 'banner-loader'出问题(如果报错) 24 | validateOptions(schema,options,'banner-loader') 25 | if(options.filename){ 26 | this.addDependency(options.filename) //自动地 添加文件依赖 加入这一句话 开启实时监控 webpack也会监控这个文件 这个文件更新也会实时更新 27 | fs.readFile(options.filename,'utf-8',function(err,data){ 28 | cb(err,`/**${data}**/${source}`) 29 | }) 30 | }else { 31 | //同步也得 cb调用了 32 | cb(null,`/**${options.text}**/${source}`) 33 | } 34 | // return source 又是异步 需要创建一个cb 35 | } 36 | 37 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/loader/css-loader.js: -------------------------------------------------------------------------------- 1 | function loader(source) { 2 | let reg = /url\((.+?)\)/g 3 | //第一次查找肯定是从零开始查找 4 | let pos = 0 5 | let arr = ['let list = []'] 6 | while(current = reg.exec(source)) { 7 | let [matchUrl,g] = current 8 | //reg.lastIndex 对应着匹配最后一个字符的长度 matchUrl对应着url('./lala.jpg')的长度 9 | //相减可以得到前边的不包含 url的值 10 | let last = reg.lastIndex - matchUrl.length 11 | arr.push(`list.push(${JSON.stringify(source.slice(pos,last))})`) 12 | //把 g 替换成ruquire的写法 13 | arr.push(`list.push('url('+ require(${g}) +')')`) 14 | pos = reg.lastIndex 15 | // 添加后边的 16 | arr.push(`list.push(${JSON.stringify(source.slice(pos))})`) 17 | arr.push(`module.exports = list.join(' ')`) 18 | return arr.join('\r\n') 19 | } 20 | return source 21 | } 22 | 23 | module.exports = loader 24 | -------------------------------------------------------------------------------- /webpack-go6/loader/file-loader.js: -------------------------------------------------------------------------------- 1 | let loaderUtils = require('loader-utils') 2 | function loader(source){ 3 | //根据当前格式 来生成图片路径 4 | let filename = loaderUtils.interpolateName(this,'[hash].[ext]',{content: source}) //根据当前内容来产生hash值 5 | this.emitFile(filename,source) //内部方法 发射文件 6 | //处理 图片 需要返回一个模块 7 | return `module.exports = "${filename}"` 8 | } 9 | loader.raw = true //返回二进制 10 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/loader/inline-loader.js: -------------------------------------------------------------------------------- 1 | function loader(source){ //loader的参数就是源代码 2 | console.log('inline') 3 | return source; 4 | } 5 | 6 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/loader/less-loader.js: -------------------------------------------------------------------------------- 1 | let less = require('less') 2 | function loader(source) { 3 | let css 4 | less.render(source,(err,r) => { 5 | css = r.css 6 | }) 7 | return css 8 | } 9 | 10 | module.exports = loader 11 | -------------------------------------------------------------------------------- /webpack-go6/loader/loader1.js: -------------------------------------------------------------------------------- 1 | function loader(source){ //loader的参数就是源代码 2 | console.log(1) 3 | return source; 4 | } 5 | 6 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/loader/loader2.js: -------------------------------------------------------------------------------- 1 | function loader(source){ //loader的参数就是源代码 2 | console.log(2) 3 | return source; 4 | } 5 | loader.pitch = function(){ 6 | return 'ok' 7 | } 8 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/loader/loader3.js: -------------------------------------------------------------------------------- 1 | function loader(source){ //loader的参数就是源代码 2 | console.log(3) 3 | return source; 4 | } 5 | 6 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/loader/style-loader.js: -------------------------------------------------------------------------------- 1 | let loaderUtils = require('loader-utils') 2 | let style = '' 3 | function loader(source) { 4 | console.log(source) 5 | return `style = document.createElement('style') 6 | style.innerHTML = ${JSON.stringify(source)} 7 | document.head.appendChild(style)` 8 | } 9 | //在 style-laoder pitch上写一个返回值 就不执行后边 没有pitch source是一个css解析完成的字符串 10 | loader.pitch = function(remainingRequest){ 11 | //loaderUtils.stringifyRequest(this,'!!'+remainingRequest) 会把绝对路径转化为相对路径 12 | // 这样做是为了 相当于引入一个inline-loader来处理css-loader返回的值 不需要再走其他的loader 需要加'!!' 13 | // 参照 pitch用法以及inline-loader使用方式来理解 14 | // 就是 把 css转化的 list数组 转化为 style-loader能看懂的 字符串 15 | return `style = document.createElement('style') 16 | style.innerHTML = require(${loaderUtils.stringifyRequest(this,'!!'+remainingRequest)}) 17 | document.head.appendChild(style)` 18 | } 19 | module.exports = loader 20 | 21 | let a = 3,b = 4 22 | [b, a] = [a, b] 23 | console.log(b) -------------------------------------------------------------------------------- /webpack-go6/loader/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | let a = 3,b = 4 2 | [b, a] = [a, b] 3 | console.log(b) -------------------------------------------------------------------------------- /webpack-go6/loader/url-loader.js: -------------------------------------------------------------------------------- 1 | let loaderUtils = require('loader-utils') 2 | // 获取后缀名 3 | let mime = require('mime') 4 | function loader(source) { 5 | let {limit} = loaderUtils.getOptions(this) 6 | if(limit && limit>source.length){ 7 | //转成base64编码 8 | return `module.exports = "data:${mime.getType(this.resourcePath)};base64,${source.toString('base64')}"` 9 | }else { 10 | // 返回file-loader this和source通过call传入 防止参数变乱 11 | return require('./file-loader').call(this,source) 12 | } 13 | } 14 | loader.raw = true //转为二进制 15 | module.exports = loader -------------------------------------------------------------------------------- /webpack-go6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-go6", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "webpack": "^4.34.0", 14 | "webpack-cli": "^3.3.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /webpack-go6/src/a.js: -------------------------------------------------------------------------------- 1 | module.exports = 'hanke' -------------------------------------------------------------------------------- /webpack-go6/src/index.js: -------------------------------------------------------------------------------- 1 | // console.log('hello') 2 | 3 | //inline-loader! 这样会运行inline-loader 4 | // -!不会通过 pre normal来处理了 5 | // !没有normal 6 | // !!什么都不要 只用inline-loader 7 | // require('inline-loader!./a.js') 8 | 9 | /* class Hanke{ 10 | constructor(){ 11 | this.name = 'hanke' 12 | } 13 | getName(){ 14 | return this.name 15 | } 16 | } 17 | var h = new Hanke() 18 | console.log(h.getName()) */ 19 | 20 | /* import p from './lala.jpg' 21 | console.log(p) 22 | let img = document.createElement('img') 23 | img.src = p 24 | document.body.appendChild(img) */ 25 | 26 | require('./index.less') -------------------------------------------------------------------------------- /webpack-go6/src/index.less: -------------------------------------------------------------------------------- 1 | @color: red; 2 | body { 3 | // background-color: @color; 4 | background: url('./lala.jpg') no-repeat; 5 | } -------------------------------------------------------------------------------- /webpack-go6/src/lala.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1better/mywebpack/d321b5393ca9d6405fcceceee4e09ada9ec696a3/webpack-go6/src/lala.jpg -------------------------------------------------------------------------------- /webpack-go6/src/tempCodeRunnerFile.js: -------------------------------------------------------------------------------- 1 | 2 | import p from './lala.jpg' 3 | console.log(p) -------------------------------------------------------------------------------- /webpack-go6/webpack.config.js: -------------------------------------------------------------------------------- 1 | let path = require("path"); 2 | module.exports = { 3 | mode: "development", 4 | entry: "./src/index.js", 5 | output: { 6 | filename: "build.js", 7 | path: path.resolve(__dirname, "dist") 8 | }, 9 | 10 | resolveLoader: { 11 | //第三种方法 配置modules 默认去node_modules下找 找不到去loader文件夹下找 12 | modules: ["node_modules", path.resolve(__dirname, "loader")] 13 | /* // //第二种方法 配置 loader别名配置别名 14 | alias:{ 15 | 'loader1':path.resolve(__dirname,'loader','loader1.js') 16 | } */ 17 | }, 18 | devtool:'source-map', 19 | // watch:true, 20 | module: { 21 | rules:[ 22 | { 23 | test: /\.less$/, 24 | use:[ 25 | 'style-loader', 26 | 'css-loader', 27 | 'less-loader' 28 | ] 29 | }, 30 | { 31 | test: /\.jpg$/, 32 | // 目的 根据图片生成一个 md5串 发射到dist目录下 file-loader还会返回当前路径 33 | /* use:{ 34 | loader: 'file-loader', 35 | } */ 36 | use:{ //符号中文 会报Invalid or unexpected token 37 | loader: 'url-loader', //url-loader会处理路径并且交给file-loader 38 | options:{ 39 | limit: 200*1024 40 | } 41 | } 42 | } 43 | /* { 44 | test: /\.js$/, 45 | use:{ 46 | loader: 'banner-loader', 47 | options:{ 48 | text: 'hanke', 49 | //如果没有给text的时候 50 | filename: path.resolve(__dirname,'banner.js') 51 | } 52 | } 53 | } */ 54 | /* { 55 | test: /\.js$/, 56 | use:{ 57 | loader: 'babel-loader', 58 | options:{ 59 | presets: [ 60 | '@babel/preset-env' 61 | ] 62 | } 63 | } 64 | } */ 65 | ] 66 | // rules: [ 67 | // /* { 68 | // test: /\.js$/, 69 | // use:[ 70 | // //找loader1的几种方式 71 | // // path.resolve(__dirname,'loader','loader1.js') 72 | // 'loader3','loader2','loader1' 73 | // //从右到左 从下到上执行 74 | // ] 75 | // } */ 76 | // { 77 | // test: /\.js$/, 78 | // use: "loader1", 79 | // enforce: "pre" 80 | // }, 81 | // { 82 | // test: /\.js$/, 83 | // use: "loader2" 84 | // }, 85 | // { 86 | // test: /\.js$/, 87 | // use: "loader3", 88 | // enforce: "post" 89 | // } 90 | // ] 91 | } 92 | }; 93 | -------------------------------------------------------------------------------- /webpack-go7/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 12 | 13 | 14 | 126 | -------------------------------------------------------------------------------- /webpack-go7/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "css-loader": "^3.0.0", 4 | "html-webpack-plugin": "^4.0.0-beta.5", 5 | "mini-css-extract-plugin": "^0.7.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /webpack-go7/plugins/AsyncPlugin.js: -------------------------------------------------------------------------------- 1 | class AsyncPlugin { 2 | 3 | apply(compiler){ 4 | //这样是一个同步代码 5 | console.log(2) 6 | compiler.hooks.emit.tapAsync('AsyncPlugin',(compliation,cb)=>{ 7 | setTimeout(()=>{ 8 | console.log('等一下') 9 | cb() 10 | },1000) 11 | }) 12 | compiler.hooks.emit.tapPromise('AsyncPlugin',(compliation)=>{ 13 | return new Promise((resolve,reject)=>{ 14 | setTimeout(()=>{ 15 | console.log('再等一下') 16 | resolve() 17 | },1000) 18 | }) 19 | }) 20 | } 21 | } 22 | module.exports = AsyncPlugin -------------------------------------------------------------------------------- /webpack-go7/plugins/DonePlugin.js: -------------------------------------------------------------------------------- 1 | class DonePlugin{ 2 | apply(compiler) // compiler.hooks 3 | { 4 | //这样是一个同步代码 5 | console.log(1) 6 | //第一个参数无所谓,放啥都可以 tapable的时候也是 7 | compiler.hooks.done.tap('DonePlugin',(states)=>{ 8 | console.log('编译完成哦哦哦') 9 | }) 10 | } 11 | } 12 | //还需要导出一下 13 | module.exports = DonePlugin -------------------------------------------------------------------------------- /webpack-go7/plugins/FileListPlugin.js: -------------------------------------------------------------------------------- 1 | class FileListPlugin { 2 | constructor({ filename }) { 3 | this.filename = filename; 4 | } 5 | apply(compiler) { 6 | //文件准备好了,要进行发射 7 | compiler.hooks.emit.tapAsync("FileListPlugin", (compilation, cb) => { 8 | // compilcation有很多的属性 9 | // 打包的资源都会放在compilcation的assets属性上 10 | // console.log(compilation.assets) 11 | let content = `## 文件名 资源大小\r\n`; 12 | let assets = compilation.assets; 13 | //Object.entries() 可以把对象变成一个数组 14 | Object.entries(assets).forEach(([filename, staObj]) => { 15 | content += `- ${filename} ${staObj.size()}\r\n`; 16 | }); 17 | 18 | assets[this.filename] = { 19 | source() { 20 | return content; 21 | }, 22 | size() { 23 | return content.length; 24 | } 25 | }; 26 | cb() 27 | }); 28 | } 29 | } 30 | module.exports = FileListPlugin; 31 | -------------------------------------------------------------------------------- /webpack-go7/plugins/InlineSourcePlugin.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | //把外链标签变成内联 3 | class InlineSourcePlugin{ 4 | constructor({test}){ 5 | this.reg = test //正则 6 | } 7 | processTag(tag,compilation) { 8 | let newTag,url 9 | if(tag.tagName==='link'&&this.reg.test(tag.attributes.href)){ 10 | newTag = { 11 | tagName: 'style', 12 | attributes: { 13 | type: 'text/css' 14 | } 15 | } 16 | url = tag.attributes.href 17 | }else if(tag.tagName==='script'&&this.reg.test(tag.attributes.src)){ 18 | newTag = { 19 | tagName: 'script', 20 | attributes: { 21 | type: 'application/javascript' 22 | } 23 | } 24 | url = tag.attributes.src 25 | } 26 | if(url){ 27 | newTag.innerHTML = compilation.assets[url].source() //文件内容 28 | //删除这一个资源 29 | delete compilation.assets[url] 30 | return newTag 31 | } 32 | return tag 33 | } 34 | processTags(data,compilation){ 35 | let bodyTags = [] 36 | let headTags = [] 37 | data.headTags.forEach(headTag => { 38 | headTags.push(this.processTag(headTag,compilation)) 39 | }) 40 | data.bodyTags.forEach(bodyTag => { 41 | bodyTags.push(this.processTag(bodyTag,compilation)) 42 | }) 43 | return {...data,headTags,bodyTags} 44 | } 45 | apply(compiler){ 46 | //要通过 HtmlWebpackPlugin的钩子来实现这一功能 根据官网文档修改 47 | compiler.hooks.compilation.tap('InlineSourcePlugin', (compilation) => { 48 | HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync( 49 | 'AfterPlugin', 50 | (data, cb) => { 51 | //将link变成内联 script变成内联 52 | data = this.processTags(data,compilation) //compilation.assets 资源 53 | cb(null, data) 54 | } 55 | ) 56 | }) 57 | } 58 | } 59 | 60 | module.exports = InlineSourcePlugin -------------------------------------------------------------------------------- /webpack-go7/src/index.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: red; 3 | } -------------------------------------------------------------------------------- /webpack-go7/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /webpack-go7/src/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' -------------------------------------------------------------------------------- /webpack-go7/webpack.config.js: -------------------------------------------------------------------------------- 1 | let path = require('path') 2 | /* let DonePlugin = require('./plugins/DonePlugin.js') 3 | let AsyncPlugin = require('./plugins/AsyncPlugin.js') */ 4 | let HtmlWebpackPlugin = require('html-webpack-plugin') 5 | let FileListPlugin = require('./plugins/FileListPlugin') 6 | let MiniCssExtractPlugin = require('mini-css-extract-plugin') 7 | let InlineSourcePlugin = require('./plugins/InlineSourcePlugin') 8 | module.exports = { 9 | mode: 'development', 10 | entry: './src/index.js', 11 | output:{ 12 | filename: 'bundle.js', 13 | path: path.resolve(__dirname,'dist') 14 | }, 15 | module:{ 16 | rules:[ 17 | { 18 | test: /\.css$/, 19 | use: [MiniCssExtractPlugin.loader,'css-loader'] 20 | } 21 | ] 22 | }, 23 | plugins:[ 24 | /* new DonePlugin(), 25 | new AsyncPlugin() */ 26 | new HtmlWebpackPlugin({ 27 | template: './src/index.html' 28 | }), 29 | /* new FileListPlugin({ 30 | filename: 'list.md' 31 | }), */ 32 | new MiniCssExtractPlugin({ 33 | filename: 'main.css' 34 | }), 35 | new InlineSourcePlugin({ 36 | test: /(\.js|css)/ 37 | }) 38 | ] 39 | } -------------------------------------------------------------------------------- /webpack笔记/webpack学习...01.md: -------------------------------------------------------------------------------- 1 | ## webpack学习...01 (对应1-11) 2 | 3 | ## 安装 4 | 5 | > ```shell 6 | > #第一步的安装 7 | > npm init -y cnpm i webpack webpack-cli -D 8 | > #-D 开发依赖,上线不需要 9 | > npx webpack #这个指令直接就默认生成dist的main.js,默认是生产环境 10 | > #支持模块化 可以用commonJS语法 11 | > #安装 挂载到内存的插件 12 | > cnpm i webpack-dev-server html-webpack-plugin -D 13 | > #安装 css-loader style-loader 解析css文件 14 | > cnpm i css-loader style-loader -D 15 | > #安装 less less-loader 解析less文件(前边的css以及style都用的到 还有一个顺序问题) 16 | > cnpm i less less-loader -D 17 | > #安装 node-sass sass-loader 解析sass文件 18 | > cnpm i node-sass sass-loader -D 19 | > #安装 mini-css-extract-plugin 抽离css 将css变成link的形式引入 20 | > cnpm i mini-css-extract-plugin -D 21 | > #安装 postcss-loader autoprefixer自动为css添加私有化前缀 22 | > cnpm i postcss-loader autoprefixer -D 23 | > #安装 optimize-css-assets-webpack-plugin 来自动压缩css文件 24 | > cnpm i optimize-css-assets-webpack-plugin -D 25 | > #安装 babel-loader @babel/core @babel/preset-env 来转换es6 语法 26 | > cnpm i babel-loader @babel/core @babel/preset-env -D 27 | > #安装 @babel/plugin-proposal-class-properties 来解析类语法 28 | > cnpm i @babel/plugin-proposal-class-properties -D 29 | > #安装 @babel/plugin-proposal-decorators 来解析 @log(decorators-legacy)这种语法 (这个没见过) 30 | > #这里的配置出现了不少错误 还是不怎么熟练 31 | > cnpm i @babel/plugin-proposal-decorators -D 32 | > #安装 @babel/plugin-transform-runtime 来处理js语法 33 | > cnpm i @babel/plugin-transform-runtime -D 34 | > cnpm i @babel/runtime #什么都不加 这个上线也用得到 35 | > #安装 @babel/polyfill 来解决高级用法的问题(如 字符串的includes用法) 36 | > cnpm i @babel/polyfill #没有 -D 37 | > #安装 eslint eslint-loader 来校验js语法 38 | > cnpm i eslint eslint-loader -D 39 | > #安装 jquery 来 测试暴露全局的loader 40 | > cnpm i jquery -D 41 | > #安装 expose-loader 来暴露全局 42 | > cnpm i expose-loader -D 43 | > #安装 file-loader 默认生成一张新的图片到build目录下 生成图片名字返回 44 | > cnpm i file-loader -D 45 | > #安装 html-with-loader 来解决 img src='' 这样的问题 46 | > cnpm i html-withimg-loader -D 47 | > #安装 url-loader 来处理图片 (一般不用file-loader来处理图片 ) 48 | > cnpm i url-loader -D 49 | > ``` 50 | > 51 | > 52 | 53 | ## 配置 webpack.config.js 54 | 55 | > ```js 56 | > const path = require("path"); 57 | > // html挂载到内存的插件 58 | > const HtmlWebpackPlugin = require("html-webpack-plugin"); 59 | > // 将css变成link引入的插件 60 | > const MiniCssExtractPlugin = require("mini-css-extract-plugin") 61 | > // 压缩css的插件 62 | > const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 63 | > const webpack = require('webpack') 64 | > 65 | > const htmlPlugin = new HtmlWebpackPlugin({ 66 | > template: './src/index.html' ,//模板 67 | > filename: 'index.html', 68 | > /* //压缩 html 69 | > minify: { 70 | > //删除属性双引号 71 | > removeAttributeQuotes:true, 72 | > //变成一行 73 | > collapseWhitespace:true, 74 | > }, 75 | > //有一个hash值 76 | > hash : true */ 77 | > }) 78 | > 79 | > // 抽离css变为link引入的形式 80 | > const miniPlugin = new MiniCssExtractPlugin({ 81 | > // 产生到css目录下 82 | > filename: 'css/main.css', 83 | > }) 84 | > // 压缩css代码 85 | > const optPlugin = new OptimizeCSSAssetsPlugin() 86 | > 87 | > //webpackPlugin 为每个模块都注入$ 88 | > const webpackPlugin = new webpack.ProvidePlugin({ 89 | > $: 'jquery' 90 | > }) 91 | > 92 | > module.exports = { 93 | > /* //压缩css文件 这是之前的老版本 现在不行了 94 | > optimization: { //优化项 new TerserJSPlugin({}), 95 | > minimizer: [ new OptimizeCSSAssetsPlugin({})], 96 | > }, */ 97 | > 98 | > /* 配置 html-webpack-plugin的第一种方法 一般不用 直接在package.json中配置就可以 99 | > devServer: { 100 | > //开发服务器的配置 101 | > port: 3000, 102 | > progress: true, 103 | > contentBase: "./src", 104 | > //启动gzip压缩 105 | > compress: true 106 | > }, */ 107 | > mode: "development", //模式 108 | > entry: "./src/index.js", //入口 109 | > output: { 110 | > // filename: "bundle.js.[hash:8]", //配置hash :8只显示8位 111 | > filename: "bundle.js", //打包后的文件名 112 | > path: path.resolve(__dirname, "dist") ,//路径必须是一个绝对路径 113 | > // publicPath: 'http://www.hanke.com'//公共的路径 114 | > }, 115 | > plugins: [ //数组 放着所有webpack的插件 116 | > htmlPlugin, 117 | > miniPlugin, 118 | > //新版本这样压缩就可以了 119 | > optPlugin, 120 | > //用webpack的插件 在每个模块中 都注入 $ 121 | > webpackPlugin 122 | > ], 123 | > //引入jquery会忽略掉(已经在cdn引入了) 124 | > externals: { 125 | > jquery: '$' 126 | > }, 127 | > module: { //模块 128 | > rules: [ 129 | > //配置 html读取img的src 130 | > { 131 | > test: /\.html$/, 132 | > use: 'html-withimg-loader' 133 | > }, 134 | > //配置 file-loader来读取图片 135 | > { 136 | > test: /\.(png|jpg|gif)$/, 137 | > //做一个限制 当小于多少k 用base64来转化 base64文件可以减少http请求 但是比原文件大3分之1 138 | > // 否则用file-loader来产生真实的图片 139 | > use: { 140 | > loader: 'url-loader', 141 | > options: { 142 | > limit: 1, 143 | > //输出的路径 144 | > outputPath: 'img/', 145 | > //只在图片中有一个公共的路径,在解析img的loader中单独配置 146 | > publicPath: 'http:/111' 147 | > } 148 | > } 149 | > }, 150 | > /* { 151 | > // 添加loader规则 就不再需要import $ from 'expose-loader?$!jquery' 这样 直接 import 152 | > // 这一步一直报错 这个方法显示未定义 不知道为什么 只好用第二个方法 导入插件了 153 | > // 哈哈哈 明白了 把下边的exclude去掉就可以了 因为它是在node_modules下边找的 这一步有点画蛇添足了,不能老是下意识地写exclude 还有 验证这个的时候把上边的 externals注释掉 不然出错 154 | > test: require.resolve('jquery'), 155 | > use: 'expose-loader?$', 156 | > // 注释掉就ok了 exclude: /node_modules/ 157 | > }, */ 158 | > /* //校验js的 先关闭 最后用到 修改 159 | > { 160 | > test: /\.js$/,use:[ 161 | > { 162 | > loader: 'eslint-loader', 163 | > options: { 164 | > //强制 pre 之前执行 post 之后 未设置为normal 普通的loader 165 | > enforce: 'pre' 166 | > } 167 | > } 168 | > ], 169 | > exclude: /node_modules/ 170 | > }, */ 171 | > 172 | > //规则 css-loader 处理css文件 解析@import这种语法 173 | > // style-loader 把css标签插入到header中 174 | > // loader的特点 单一 175 | > // loader的用法 字符串只用一个loader 多个需要数组 176 | > // loader 的顺序 默认从右到左执行 从下到上执行 177 | > /* 178 | > test:/\.css$/, use:[ 179 | > 'style-loader' 180 | > ,'css-loader'] } 181 | > */ 182 | > // 也可以写成对象,可以多传入一个参数 183 | > { 184 | > test:/\.css$/, use:[ 185 | > { 186 | > loader:'style-loader', 187 | > options: { 188 | > //将style标签插入到顶部 189 | > insertAt: 'top' 190 | > } 191 | > }, 192 | > 'css-loader', 193 | > //为loader添加私有化前缀 194 | > 'postcss-loader', 195 | > ] 196 | > }, 197 | > /* //配置less 198 | > { 199 | > test:/\.less$/, use:[ 200 | > { 201 | > loader:'style-loader', 202 | > options: { 203 | > //将style标签插入到顶部 204 | > insertAt: 'top' 205 | > } 206 | > }, 207 | > 'css-loader', 208 | > 'less-loader' //less -> css 209 | > ] 210 | > } */ 211 | > //抽离为 212 | > { 213 | > test:/\.less$/, use:[ 214 | > MiniCssExtractPlugin.loader, 215 | > 'css-loader', 216 | > 'postcss-loader', 217 | > 'less-loader' //less -> css 218 | > ] 219 | > }, 220 | > /* 配置babel */ 221 | > { 222 | > test: /\.js$/, 223 | > use: [ 224 | > { 225 | > loader: 'babel-loader', 226 | > options: { 227 | > presets: [ 228 | > '@babel/preset-env' 229 | > ], 230 | > plugins: [ 231 | > // '@babel/plugin-proposal-class-properties' 解析class 232 | > // 上边边解析 @log 233 | > ["@babel/plugin-proposal-decorators", { "legacy": true }], 234 | > ['@babel/plugin-proposal-class-properties', { "loose": true}], 235 | > '@babel/plugin-transform-runtime' 236 | > 237 | > ] 238 | > } 239 | > } 240 | > ], 241 | > //包括 242 | > include: path.resolve(__dirname,'src'), 243 | > //排除 244 | > exclude: /node_modules/ 245 | > } 246 | > ] 247 | > } 248 | > }; 249 | > 250 | > ``` 251 | > 252 | > 253 | 254 | ## index.js(测试用) 255 | 256 | > ```js 257 | > // import $ from 'jquery' 258 | > //默认 是 立即执行函数的loader 不会暴露全局变量 259 | > //expose-loader 暴露全局的loader 内联的loader 260 | > //pre post normal 261 | > 262 | > // 暴露出去 下边是写法规范 263 | > // import $ from 'expose-loader?$!jquery' 264 | > // console.log($) 265 | > //file-loader 图片引入 返回一个新图片地址 266 | > import logo from './logo.jpg' 267 | > console.log(logo) 268 | > let img = new Image() 269 | > img.src = logo 270 | > document.body.appendChild(img) 271 | > 272 | > // require('@babel/polyfill') 273 | > // require("./a.js"); 274 | > 275 | > // console.log("ok"); 276 | > 277 | > // require('./index.css') 278 | > require('./index.less') 279 | > 280 | > // let fn = () => { 281 | > // console.log(2222) 282 | > // } 283 | > 284 | > // fn() 285 | > 286 | > // function *gen () { 287 | > // yield 1; 288 | > // } 289 | > // console.log(gen().next()) 290 | > 291 | > 292 | > // console.log('aaa'.includes('a')) 293 | > 294 | > // class B { 295 | > // c = 2; 296 | > // } 297 | > /* @log 298 | > class A { 299 | > a = 1; 300 | > } 301 | > var a = new A() 302 | > console.log(a.a) 303 | > 304 | > //这个装饰 没有学过 305 | > function log(target) { 306 | > console.log(target) 307 | > } */ 308 | > ``` 309 | > 310 | > 311 | 312 | ## 配置 package.json 313 | 314 | > ```json 315 | > //重要内容 注意 这样是不对的 json标准中不允许有解析 316 | > "scripts": { 317 | > "build": "webpack", 318 | > "dev": "webpack-dev-server --open --port 3000 --hot " 319 | > } 320 | > ``` 321 | > 322 | > 323 | 324 | ## (webpack打包出来最简易的bundle.js) 325 | 326 | > ```js 327 | > (function(modules) { // webpackBootstrap webpack入口函数 328 | > // The module cache 定义一个缓存 329 | > var installedModules = {}; 330 | > // The require function 配置实现了 require方法 331 | > function __webpack_require__(moduleId) { 332 | > // Check if module is in cache 检查是否在缓存中 333 | > if(installedModules[moduleId]) { 334 | > return installedModules[moduleId].exports; 335 | > } 336 | > // Create a new module (and put it into the cache) 337 | > var module = installedModules[moduleId] = { 338 | > i: moduleId, 339 | > l: false, 340 | > exports: {} 341 | > }; 342 | > // Execute the module function call方法 343 | > modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 344 | > // Flag the module as loaded 345 | > module.l = true; 346 | > // Return the exports of the module 返回module.exports 347 | > return module.exports; 348 | > } 349 | > return __webpack_require__(__webpack_require__.s = "./src/index.js");//入口模块 350 | > }) 351 | > ({ 352 | > "./src/a.js": //key->模块的路径 353 | > /*! no static exports found */ 354 | > (function(module, exports) { //value函数 355 | > eval("console.log('我能行')\n\n//# sourceURL=webpack:///./src/a.js?"); 356 | > }), 357 | > "./src/index.js": 358 | > (function(module, exports, __webpack_require__) { 359 | > //递归 先执行./src/a.js 再执行index.js下边的方法 360 | > eval("__webpack_require__(/*! ./a.js */ \"./src/a.js\")\r\n\r\nconsole.log('ok')\n\n//# sourceURL=webpack:///./src/index.js?"); 361 | > }) 362 | > }); 363 | > ``` 364 | > 365 | > 366 | 367 | ## 为什么是webpack.config.js 368 | 369 | > ```js 370 | > //node_modules 下的webpack-cli 下的bin下的config中的config-yargs.js的这一句话 371 | > defaultDescription: "webpack.config.js or webpackfile.js", 372 | > ``` 373 | > 374 | > 375 | 376 | ## webpack.config.js改名之后运行 377 | 378 | > ```shell 379 | > npx webpack --config webpack.config.my.js 380 | > ``` 381 | > 382 | >或者 **package.json中配置** 383 | > 384 | >```json 385 | > "scripts": { 386 | > "build" : "webpack --config webpack.config.my.js" 387 | > } 388 | > //执行 npm run build 389 | > "scripts": { 390 | > "build" : "webpack " 391 | > } 392 | > //执行 npm run build -- --config webpack.config.my.js 393 | > ``` 394 | > 395 | > 396 | 397 | ## 引入第三方模块 398 | 399 | > 1. expose-loader 暴露给全局 window 400 | > 2. ProvidePlugin 给每个都提供一个 401 | > 3. 引入 不打包的方式 402 | 403 | ## webpack打包图片 404 | 405 | > 1. js创建图片来引入 406 | > 407 | > ​ 图片引入时 采用 Import的方式引入的是一个新的图片 408 | > 409 | > 2. css引入background() 410 | >3. 411 | 412 | ## postcss.config.js配置(添加私有化前缀时需要配置) 413 | 414 | > ```js 415 | > module.exports = { 416 | > plugins: [require('autoprefixer')] 417 | > } 418 | > ``` 419 | 420 | ## .eslintrc.json 421 | 422 | > 直接在eslint官网生成 423 | 424 | -------------------------------------------------------------------------------- /webpack笔记/webpack学习...02.md: -------------------------------------------------------------------------------- 1 | ## webpack学习...02 (对应12-19) 2 | 3 | ## (ps path.resolve 老是写错 耽误很长很长时间!) 4 | 5 | ## 安装 6 | 7 | > ```shell 8 | > # 安装clean-webpack-plugin 每次打包先清除dist目录下的文件 9 | > cnpm i clean-webpack-plugin -D 10 | > # 安装copy-webpack-plugin 打包时可以把一些文件夹的内容拷贝到其他文件夹 11 | > cnpm i copy-webpack-plugin -D 12 | > # webpack 自带的插件 可以加入注释声明谁开发的 webpack.BannerPlugin() 13 | > # 安装webpack-dev-middleware webpack开发服务的一个中间件 14 | > cnpm i webpack-dev-middleware -D 15 | > # webpack 自带的插件 判断开发环境 webpack.DefinePlugin() 16 | > # 安装webpack-merge 来区分不同的环境 有webpack.base.js webpack.dev.js webpack.pro.js 17 | > cnpm i webpack-merge -D 18 | > ``` 19 | > 20 | > 21 | 22 | ## 打包多页应用 23 | 24 | > ```js 25 | > //多入口需要写成一个对象 26 | > //两个入口 27 | > mode: 'development', 28 | > entry: { 29 | > //首页 30 | > home: './src/index.js', 31 | > //other页相关 32 | > other: './src/other.js' 33 | > }, 34 | > //两个出口 35 | > output:{ 36 | > // name代表 home或者other .[hash] 给文件加一个hash串 37 | > // filename: '[name].[hash].js', 38 | > filename: '[name].js', 39 | > path: path.resolve(__dirname,'dist') 40 | > }, 41 | > ``` 42 | > 43 | > 44 | 45 | ## dev-tool的四个选项 46 | 47 | > ```js 48 | > // 增加 devtool 源码映射 可以很方便的调试源代码 49 | > // 源码映射 单独生成一个 source-map文件 出错会标识出错的列和行 大和全 50 | > devtool:'source-map', 51 | > 52 | > // 不会单独生成一个文件 但会显示行和列 53 | > devtool: 'eval-source-map', 54 | > 55 | > // 不会产生单独列 但会生成一个映射文件 56 | > devtool: 'cheap-module-source-map', //保留 后来调试用 57 | > // 不会单独生成文件 集成在打包文件中 也不产生列 58 | > devtool: 'cheap-module-eval-source-map', 59 | > ``` 60 | > 61 | > 62 | 63 | ## webpack跨域问题 64 | 65 | > ```js 66 | > // server.js 67 | > // 1 68 | > const express = require('express') 69 | > let app = express() 70 | > app.get('/api/user',(req,res)=>{ 71 | > res.json({ 72 | > name: 'myname222' 73 | > }) 74 | > }) 75 | > app.listen(3500) 76 | > //2 77 | > const express = require('express') 78 | > let app = express() 79 | > app.get('/user',(req,res)=>{ 80 | > res.json({ 81 | > name: 'myname222' 82 | > }) 83 | > }) 84 | > app.listen(3500) 85 | > ``` 86 | > 87 | > **对应解决方法** 88 | > 89 | > ```js 90 | > devServer:{ 91 | > //这是 服务器为 /api/user 1解决方法 92 | > proxy : { 93 | > '/api':'http://localhost:3500' 94 | > } 95 | > // /user的用法 2解决方法 96 | > proxy: { 97 | > '/api': { 98 | > target: 'http://localhost:3500', 99 | > pathRewrite: { 100 | > '/api':'/' 101 | > } 102 | > } 103 | > } 104 | > //前端只想单纯模拟方法 105 | > before(app){ //提供的方法 相当于钩子 106 | > //写这些代码就不存在跨域问题 107 | > app.get('/user',(req,res)=>{ 108 | > res.json({ 109 | > name: 'myname-before' 110 | > }) 111 | > }) 112 | > } 113 | > 114 | > //有服务端,但是不用代理来处理 在服务器端开启webpack 端口用服务端端口 115 | > //server.js 后端加前端合在一起解决跨域 116 | > //webpack自带一个express 117 | > let express = require('express') 118 | > let app = express() 119 | > let webpack = require('webpack') 120 | > //需要使用中间件 需要安装 121 | > let middle = require('webpack-dev-middleware') 122 | > let config = require('./webpack.config.js') 123 | > let compiler = webpack(config) 124 | > app.use(middle(compiler)) 125 | > app.get('/api/user',(req,res)=>{ 126 | > res.json({ 127 | > name: 'myname222' 128 | > }) 129 | > }) 130 | > app.listen(3500) 131 | > ``` 132 | > 133 | > 134 | 135 | ## watch监视 136 | 137 | > ```js 138 | > //监控 实时打包 类似node里边那个实时监控的 139 | > watch: true, 140 | > //监控的选项 141 | > watchOptions: { 142 | > poll: 1000, //每秒问1000次 143 | > aggregateTimeout: 500 ,//防抖 (类似于函数防抖) 144 | > ignored: /node_modules/ //忽略哪个文件 145 | > }, 146 | > ``` 147 | > 148 | > 149 | 150 | ## resolve属性 151 | 152 | > ```js 153 | > resolve: { 154 | > //指定解析的模块 155 | > modules: [path.resolve('node_modules')], 156 | > // mainFiles: [],//入口文件的名字 默认找index.js 157 | > //或者用 mainFields 入口的字段 先找style 再找main 158 | > mainFields: ['style','main'], 159 | > //扩展名 可以省略 需配置 extensions 依次解析 160 | > extensions: ['.js','.css','.json'] 161 | > //别名 如 vue的vue-runtime和那个@ 162 | > // alias: { 163 | > // bootstrap: 'bootstrap/dist/css/bootstrap.css' 164 | > // } 165 | > } 166 | > ``` 167 | > 168 | > 169 | 170 | ## 生产或者开发环境配置 171 | 172 | > ```js 173 | > //webpack.pro.js 174 | > let {smart} = require('webpack-merge') 175 | > let base = require('./webpack.config.js') 176 | > module.exports = smart(base,{ 177 | > mode:'production' 178 | > }) 179 | > //webpack.dev.js 180 | > let {smart} = require('webpack-merge') 181 | > let base = require('./webpack.config.js') 182 | > module.exports = smart(base,{ 183 | > mode:'development' 184 | > }) 185 | > ``` 186 | > 187 | > 188 | 189 | ## webpack.config.js 190 | 191 | > ```js 192 | > const path = require("path"); 193 | > const HtmlWpackPlugin = require('html-webpack-plugin') 194 | > //内置插件 版权归谁谁谁所有 先导入webpack 195 | > const webpack = require('webpack') 196 | > 197 | > 198 | > //copy插件 199 | > const copyWpackPlugin = require('copy-webpack-plugin') 200 | > 201 | > // bannerPlugin 版权声明 202 | > const bannerPlugin = new webpack.BannerPlugin('make by hanke ,i will become success!') 203 | > // 这个是错误写法 正确写法 应该是解构赋值那样写 说明这个插件包含许多东西 204 | > // const CleanWebpackPlugin = require('clean-webpack-plugin') 205 | > const { CleanWebpackPlugin } = require('clean-webpack-plugin') 206 | > 207 | > //拷贝文件 208 | > const copyPlugin = new copyWpackPlugin( 209 | > //接受一个数组 可以多个文件 210 | > [{from:'./doc',to:'./'}] 211 | > ) 212 | > 213 | > // 三个其他的小插件 214 | > // 1. cleanWebpackPlugin // 每次打包会把dist目录下的文件都删除 重新打包 215 | > // 2. copyWebpackPlugin 216 | > // 3. bannerPlugin 217 | > // 前两个 需要第三方模块 第三个内置 218 | > 219 | > 220 | > // 判断开发环境的插件 DefinePlugin 221 | > const definePlugin = new webpack.DefinePlugin({ 222 | > DEV: JSON.stringify('production') 223 | > }) 224 | > // 也可以传入一个数组 告诉清理哪些文件夹 225 | > const cleanPlugin = new CleanWebpackPlugin() 226 | > 227 | > const htmlPlugin1 = new HtmlWpackPlugin({ 228 | > template: './src/index.html', 229 | > //多个 html 230 | > filename: 'home.html', 231 | > //代码块 232 | > chunks: ['home'] 233 | > }) 234 | > const htmlPlugin2 = new HtmlWpackPlugin({ 235 | > template: './src/index.html', 236 | > //多个 html 237 | > filename: 'other.html', 238 | > //代码块 放置引入的东西 239 | > chunks: ['other'] 240 | > }) 241 | > 242 | > const htmlPlugin = new HtmlWpackPlugin({ 243 | > template: './src/index.html', 244 | > //多个 html 245 | > filename: 'index.html', 246 | > }) 247 | > module.exports = { 248 | > //多入口需要写成一个对象 249 | > //两个入口 250 | > mode: 'development', 251 | > entry: { 252 | > /* //首页 253 | > home: './src/index.js', 254 | > //other页相关 255 | > other: './src/other.js' */ 256 | > 257 | > index: './src/index.js' 258 | > }, 259 | > //两个出口 260 | > output:{ 261 | > // name代表 home或者other .[hash] 给文件加一个hash串 262 | > // filename: '[name].[hash].js', 263 | > filename: '[name].js', 264 | > path: path.resolve(__dirname,'dist') 265 | > }, 266 | > /* //监控 实时打包 类似node里边那个实时监控的 267 | > watch: true, 268 | > //监控的选项 269 | > watchOptions: { 270 | > poll: 1000, //每秒问1000次 271 | > aggregateTimeout: 500 ,//防抖 (类似于函数防抖) 272 | > ignored: /node_modules/ //忽略哪个文件 273 | > }, */ 274 | > //增加 devtool 源码映射 可以很方便的调试源代码 275 | > // 源码映射 单独生成一个 source-map文件 出错会标识出错的列和行 大和全 276 | > // devtool:'source-map', 277 | > 278 | > // 不会单独生成一个文件 但会显示行和列 279 | > // devtool: 'eval-source-map', 280 | > 281 | > // 不会产生单独列 但会生成一个映射文件 282 | > //devtool: 'cheap-module-source-map', //保留 后来调试用 283 | > // 不会单独生成文件 集成在打包文件中 也不产生列 284 | > devtool: 'cheap-module-eval-source-map', 285 | > plugins: [ 286 | > // 打包多页面 287 | > // htmlPlugin1, 288 | > // htmlPlugin2 289 | > 290 | > //学习 source-map使用 291 | > htmlPlugin, 292 | > // 清除插件 293 | > cleanPlugin, 294 | > // 复制插件 295 | > copyPlugin, 296 | > // 内置插件 添加注释 297 | > bannerPlugin, 298 | > // 内置插件 判断开发环境 299 | > definePlugin 300 | > ], 301 | > //解析第三方模块 commen 302 | > resolve: { 303 | > //指定解析的模块 304 | > modules: [path.resolve('node_modules')], 305 | > //或者用 mainFields 入口的字段 先找style 再找main 306 | > // mainFiles: [],//入口文件的名字 默认找index.js 307 | > mainFields: ['style','main'], 308 | > //扩展名 可以省略 需配置 extensions 依次解析 309 | > extensions: ['.js','.css','.json'] 310 | > //别名 如 vue的vue-runtime和那个@ 311 | > // alias: { 312 | > // bootstrap: 'bootstrap/dist/css/bootstrap.css' 313 | > // } 314 | > }, 315 | > module: { 316 | > rules: [ 317 | > { 318 | > test: /\.css$/, 319 | > use:['style-loader','css-loader'] 320 | > }, 321 | > { 322 | > test: /\.js$/, 323 | > use: { 324 | > loader: 'babel-loader', 325 | > options: { 326 | > presets: ['@babel/preset-env'] 327 | > } 328 | > }, 329 | > exclude: /node_modules/ 330 | > } 331 | > ] 332 | > }, 333 | > //跨域问题的设置 334 | > devServer:{ 335 | > //这是 服务器为 /api/user 336 | > /* proxy : { 337 | > '/api':'http://localhost:3500' 338 | > } */ 339 | > // /user的用法 340 | > /* proxy: { 341 | > // 重写的方式 把请求代理到express服务器上 342 | > '/api': { 343 | > target: 'http://localhost:3500', 344 | > pathRewrite: { 345 | > '/api':'/' 346 | > } 347 | > } 348 | > } */ 349 | > //前端只想单纯模拟方法 350 | > /* before(app){ //提供的方法 相当于钩子 351 | > //写这些代码就不存在跨域问题 352 | > app.get('/user',(req,res)=>{ 353 | > res.json({ 354 | > name: 'myname-before' 355 | > }) 356 | > }) 357 | > } */ 358 | > //有服务端,但是不用代理来处理 在服务器端开启webpack 端口用服务端端口 359 | > } 360 | > } 361 | > ``` 362 | > 363 | > 364 | 365 | ## index.js(测试用) 366 | 367 | > ```js 368 | > // class B { 369 | > // constructor() { 370 | > // console.log('11111') 371 | > // } 372 | > // } 373 | > // // console.log('a') 374 | > // var b = new B() 375 | > // import 'bootstrap' 376 | > // import './style' 377 | > /* let xhr = new XMLHttpRequest() 378 | > 379 | > xhr.open('GET','/api/user',true) 380 | > 381 | > xhr.onload = function() { 382 | > console.log(xhr.response) 383 | > } 384 | > 385 | > xhr.send() */ 386 | > let url = '' 387 | > if(DEV==='dev') { 388 | > url = 'localhost' 389 | > }else { 390 | > url = 'hanke' 391 | > } 392 | > console.log(url) 393 | > ``` 394 | > 395 | > -------------------------------------------------------------------------------- /webpack笔记/webpack学习...03.md: -------------------------------------------------------------------------------- 1 | ## webpcak学习...03 2 | 3 | ## 安装 4 | 5 | > ```shell 6 | > #实现安装 7 | > cnpm i webpack webpack-cli html-webpack-plugin @babel/core babel-loader @babel/preset-env @babel/preset-react webpack-dev-server -D 8 | > #安装jquery进行优化测试 9 | > cnpm i jquery 10 | > #安装moment 时间插件 11 | > cnpm i moment 12 | > #webpack内置插件 IgnorePlugin 优化 13 | > #安装 react react-dom 来测试动态链接库 14 | > cnpm i react react-dom 15 | > #webpack内置插件 DllPlugin 产生一个manifest.json 16 | > #webpack内置插件 DllReferencePlugin 得到一个manifest.json 17 | > #安装 happypack来多线程打包webpack 适合项目比较大的时候使用 18 | > cnpm i happypack -D 19 | > #安装 @babel/plugin-syntax-dynamic-import -D 来转换es6草案语法 20 | > cnpm i @babel/plugin-syntax-dynamic-import -D 21 | > #webpack 自带插件 HotModuleReplacementPlugin和 NamedModulesPlugin实现热更新 22 | > ``` 23 | > 24 | > 25 | 26 | ## webpack优化项 27 | 28 | > ```js 29 | > //1. 不去解析jquery中的依赖库 30 | > noParse: /jquery/, 31 | > //2. webpack自带的IgnorePlugin 忽略掉moment中locale引入的东西 32 | > const ignorePlugin = new webpack.IgnorePlugin(/\.\/locale/,/moment/) 33 | > //3. 包含与排除 34 | > exclude: /node_modules/, 35 | > include: path.resolve('src') 36 | > //4. 连接库的建立 (和后续webpack.react.js以及 DllPlugin DllReferencePlugin使用) 37 | > //5. happypack多线程打包webpack 38 | > //6. webpack自带优化 39 | > // tree-shaking 40 | > import calc from './test' 41 | > console.log(calc.sum(1,2)) 42 | > // import 在生产环境下会自动清除没用的东西 43 | > // 相当于tree-shaking 没用代码自动删除 44 | > // import 可以 但是 require就不行 45 | > // scope hosting 作用域提升 46 | > let a = 1 47 | > let b = 2 48 | > let c = 3 49 | > let d = a+b+c //webpack会自动省略可以简化的代码 50 | > console.log(d+'------') 51 | > ``` 52 | > 53 | > 54 | 55 | ## 抽取公共代码 56 | 57 | > ```js 58 | > // webpack.config.js中的配置 抽取公共模块 59 | > // index引入 a b other也引入 a b 60 | > optimization: { 61 | > splitChunks:{ //分割代码块 62 | > cacheGrops:{ //缓存组 63 | > common:{ //公共模块 64 | > chunks: 'initial', //入口从哪找 65 | > minSize: 0 , //大于0个字节 66 | > minChunks: 0 //引用0次 67 | > } 68 | > } 69 | > }, 70 | > vendor: { //抽离第三方模块 比如jquery 71 | > priority: 1, //先抽离第三方模块 72 | > test: /node_modules/, //引入 73 | > chunks: 'initial', // 74 | > minSize: 0 , // 75 | > minChunks: 0 // 76 | > } 77 | > } 78 | > ``` 79 | > 80 | > 81 | 82 | ## webpack懒加载 83 | 84 | > ```js 85 | > //需要babel配置 (@babel/plugin-syntax-dynamic-import) 86 | > // 生成 两个文件 用另一个时候再加载 (http访问) 87 | > let button = document.createElement('button') 88 | > button.innerHTML = 'hello' 89 | > //vue react懒加载 都是这样 90 | > button.addEventListener('click',()=>{ 91 | > //es6草案中的语法 实现jsonp动态加载文件 92 | > import ('./source.js') .then(data=>{ 93 | > console.log(data.default) 94 | > }) 95 | > }) 96 | > document.body.append(button) 97 | > ``` 98 | > 99 | > 100 | 101 | ## webpack热更新 102 | 103 | > ```js 104 | > //热更新的概念 只更新页面的一部分 不全部更新 105 | > import str from './source.js' 106 | > console.log(str) 107 | > if(module.hot) { 108 | > module.hot.accept('./source.js',()=>{ 109 | > //import只能写在页面的顶端 110 | > let str = require('./source.js') 111 | > console.log(str.default) 112 | > }) 113 | > } 114 | > ``` 115 | > 116 | > 117 | 118 | ## webpack.config.js 119 | 120 | > ```js 121 | > const path = require('path') 122 | > const webpack = require('webpack') 123 | > const HtmlWebpackPlugin = require('html-webpack-plugin') 124 | > 125 | > // 模块 happypack 来多线程打包webpack 进程(node中线程与进程关系) 打包文件会加快(文件很小时可能会变慢) 126 | > // const Happypack = require('happypack') 127 | > 128 | > const htmlPlugin = new HtmlWebpackPlugin({ 129 | > template: './public/index.html', 130 | > }) 131 | > 132 | > //webpack自带的IgnorePlugin 忽略掉moment中locale引入的东西 133 | > const ignorePlugin = new webpack.IgnorePlugin(/\.\/locale/,/moment/) 134 | > 135 | > //webpack自带的 动态引入链接库 136 | > const dllReferencePlugin = new webpack.DllReferencePlugin({ 137 | > manifest: path.resolve(__dirname,'dist','manifest.json') 138 | > }) 139 | > // happyplugin配置 140 | > // const happyPlugin = new Happypack({ 141 | > // id:'js', 142 | > // use: [{ 143 | > // loader:'babel-loader', 144 | > // options: { 145 | > // presets: [ 146 | > // '@babel/preset-env', 147 | > // '@babel/preset-react', 148 | > // ] 149 | > // } 150 | > // }] 151 | > // }) 152 | > 153 | > // 热更新所需插件 154 | > const hotPlugin = new webpack.HotModuleReplacementPlugin() 155 | > const namePlugin = new webpack.NamedModulesPlugin() //打印名字 156 | > module.exports = { 157 | > mode: "development", 158 | > /* optimization: { 159 | > splitChunks:{ //分割代码块 160 | > cacheGrops:{ //缓存组 161 | > common:{ //公共模块 162 | > chunks: 'initial', //入口从哪找 163 | > minSize: 0 , //大于0个字节 164 | > minChunks: 0 //引用0次 165 | > } 166 | > }, 167 | > vendor: { //抽离第三方模块 168 | > priority: 1, //先抽离第三方模块 169 | > test: /node_modules/, //引入 170 | > chunks: 'initial', //入口从哪找 171 | > minSize: 0 , //大于0个字节 172 | > minChunks: 0 //引用0次 173 | > } 174 | > } 175 | > }, */ 176 | > entry: { 177 | > index:'./src/index.js', 178 | > //测试抽取公共代码用 179 | > // other:'./src/other.js' 180 | > }, 181 | > output: { 182 | > filename: 'index.js', 183 | > path: path.resolve(__dirname,'dist'), 184 | > }, 185 | > //在package.json中配置 好像不起作用 不知道为啥子 不默认打开dist目录 先用这种方法吧 186 | > devServer:{ 187 | > //热更新 188 | > hot: true, 189 | > port: 3000, 190 | > open: true, 191 | > contentBase: './dist' 192 | > }, 193 | > plugins: [ 194 | > htmlPlugin, 195 | > //忽略插件 196 | > ignorePlugin, 197 | > //引入链接库插件 198 | > dllReferencePlugin, 199 | > //多线程打包文件 200 | > // happyPlugin 201 | > // 热更新的两个插件 202 | > hotPlugin, 203 | > namePlugin 204 | > ], 205 | > module:{ 206 | > //不去解析jquery中的依赖库 207 | > noParse: /jquery/, 208 | > rules:[ 209 | > { 210 | > test: /\.js$/, 211 | > //指定一个id 可能css也需要多线程打包 212 | > // use: 'Happypack/loader?id=js', 213 | > use: { 214 | > loader:'babel-loader', 215 | > options: { 216 | > presets: [ 217 | > '@babel/preset-env', 218 | > '@babel/preset-react', 219 | > ], 220 | > plugins: [ 221 | > '@babel/plugin-syntax-dynamic-import' 222 | > ] 223 | > } 224 | > }, 225 | > exclude: /node_modules/ 226 | > } 227 | > ] 228 | > } 229 | > 230 | > } 231 | > ``` 232 | > 233 | > 234 | 235 | ## webpack.react.js(输出manifest.json) 236 | 237 | > ```js 238 | > const path = require('path') 239 | > const webpack = require('webpack') 240 | > 241 | > //webpack自带插件 变成动态链接库 242 | > const dllPlugin = new webpack.DllPlugin({ //name==library 243 | > name: '_dll_[name]', 244 | > //manifest.json就是一个任务清单 245 | > path: path.resolve(__dirname,'dist','manifest.json') 246 | > }) 247 | > 248 | > module.exports = { 249 | > mode: 'development', 250 | > entry: { 251 | > // test: './src/test.js' 252 | > react: ['react','react-dom'] 253 | > }, 254 | > output: { 255 | > filename: '_dll_[name].js', //产生文件名 256 | > path: path.resolve(__dirname,'dist'), 257 | > //指定 var a = '...' 258 | > library: '_dll_[name]', 259 | > //配置commonjs 会变成export["ab"] 配置umd会变成umd模式 可配置 commonjs var this 主要用var(默认就是) 260 | > //libraryTarget: 'var' 261 | > }, 262 | > plugins: [ 263 | > //导出 manifest.json 以及 _dll_react.js 264 | > dllPlugin 265 | > ] 266 | > } 267 | > ``` 268 | > 269 | > -------------------------------------------------------------------------------- /webpack笔记/webpack学习...04.md: -------------------------------------------------------------------------------- 1 | ## webpack学习...04 2 | 3 | ## 安装 4 | 5 | > ```shell 6 | > # 安装tapable 7 | > cnpm i tapable 8 | > ``` 9 | > 10 | > 11 | 12 | ## Tapable 13 | 14 | > 介绍:本质是一种事件流的机制,核心是把各个插件串联起来,实现这一核心的就是Tapable,类似于nodejs的events库,采用的发布订阅的模式 15 | 16 | ## PS 17 | 18 | > forEach是并行操作 19 | > 20 | > 一共有三个文件夹 分别对应着同步 异步并行 异步串行的各个方法以及实现 -------------------------------------------------------------------------------- /webpack笔记/webpack学习...05.md: -------------------------------------------------------------------------------- 1 | ## webpack学习...05 2 | 3 | ## 安装 4 | 5 | > ```shell 6 | > cnpm i webpack webpack-cli -D 7 | > #如果 之前没有安装过 npx 8 | > npm i npx -g 9 | > #安装 babelon 把源码解析成AST @babel/traverse 遍历节点 @babel-types 节点替换 @babel-generator 生成 10 | > cnpm i babylon @babel/traverse @babel/types @babel/generator 11 | > #安装ejs来渲染模板(类似于tempalte-active) 12 | > cnpm i ejs 13 | > #安装less 来测试loader 14 | > cnpm i less 15 | > #安装tapable 来测试plugins 16 | > cnpm i tapable 17 | > ``` 18 | > 19 | > 20 | 21 | ## package.json 22 | 23 | > ```json 24 | > "bin":{ 25 | > "hanke-webpack": "./bin/hanke-webpack.js" 26 | > } 27 | > ``` 28 | > 29 | > bin相当于运行哪一个命令,执行哪一个文件 30 | 31 | ## npm link的流程 32 | 33 | > ```shell 34 | > #在hanke-webpack目录下 注意package.json中的bin配置以及后边是bin目录下的hanke-webpack.js 35 | > npm link 36 | > #在webpack-go5下 37 | > npm link hanke-webpack 38 | > 39 | > #注意 这样npm link后可以直接使用hanke-webpack.cmd 就可以在webpack-go5下边运行了 40 | > ``` 41 | > 42 | > 43 | 44 | ## hanke-webpack.js最开始配置 45 | 46 | > ```js 47 | > // 这一步 出错了 一个多小时 实际上就是 在自己电脑 nodejs中的global (npm link 后)添加了一个 hanke-webpack.cmd 和一个 hanke-webpack文件 然后 可以 hanke-webpack这样直接执行 48 | > // 因为路径写错了导致一直出错 49 | > #! F:/nodejs/node.exe //这里对应着自己node的下载地方 50 | > let path = require('path') 51 | > 52 | > let config = require(path.resolve('webpack.config.js')) 53 | > 54 | > let Compiler = require('../lib/Compiler') 55 | > 56 | > let compiler = new Compiler(config) 57 | > 58 | > //入口函数 59 | > compiler.hooks.entryOption.call() 60 | > 61 | > compiler.run() 62 | > 63 | > ``` 64 | > 65 | > 66 | 67 | ## compile.js 68 | 69 | > ```js 70 | > const fs = require('fs') 71 | > const path = require('path') 72 | > const babylon = require('babylon') 73 | > const types = require('@babel/types') 74 | > //es6模块 需要.defalut 75 | > const traverse = require('@babel/traverse').default 76 | > const generator = require('@babel/generator').default 77 | > //babelon 把源码解析成AST 78 | > //@babel/traverse 遍历节点 79 | > //@babel/types 节点替换 80 | > //@babel/generator 生成 81 | > const {SyncHook } = require('tapable') 82 | > const ejs = require('ejs') 83 | > //引入ejs 84 | > class Compiler{ 85 | > constructor(config){ 86 | > // entry output 87 | > this.config = config 88 | > // 保存文件路径 89 | > this.entryId //'./src/index.js' 90 | > // 保存所有模块依赖 91 | > this.modules = {} 92 | > this.entry = config.entry 93 | > //可能输出多个文件 94 | > this.assets = {} 95 | > //表示 工作路径 96 | > this.root = process.cwd() 97 | > //模拟webpack的声明周期 98 | > this.hooks = { 99 | > entryOption: new SyncHook(), 100 | > compile: new SyncHook(), 101 | > afterCompile: new SyncHook(), 102 | > afterPlugins: new SyncHook(), 103 | > run: new SyncHook(), 104 | > emit: new SyncHook(), 105 | > done: new SyncHook() 106 | > } 107 | > let plugins = this.config.plugins 108 | > //如果是数组 109 | > if(Array.isArray(plugins)){ 110 | > plugins.forEach(plugin=>{ 111 | > plugin.apply(this) 112 | > }) 113 | > } 114 | > this.hooks.afterPlugins.call() 115 | > 116 | > } 117 | > // 得到文件内容 118 | > getSource(modulePath) { 119 | > let content = fs.readFileSync(modulePath,'utf-8') 120 | > //处理 ./index.less 121 | > let rules = this.config.module.rules 122 | > rules.forEach(rule=>{ 123 | > let {test,use} = rule 124 | > let len = use.length - 1 125 | > if(test.test(modulePath)){ 126 | > (function normalLoader() { 127 | > //后边是一个绝对路径 128 | > let loader = require(use[len--]) 129 | > content = loader(content) 130 | > if(len>=0){ 131 | > normalLoader() 132 | > } 133 | > })() 134 | > 135 | > } 136 | > }) 137 | > 138 | > return content 139 | > } 140 | > // 解析源码 141 | > parse(source,parentPath) { //主要靠AST解析语法树 142 | > let ast = babylon.parse(source) 143 | > let dependencies = []//数组依赖 144 | > traverse(ast,{ 145 | > // 调用表达式 a执行 require执行 146 | > CallExpression(p){ 147 | > let node = p.node //对应的节点 148 | > if(node.callee.name === 'require') { 149 | > node.callee.name = '__webpack_require__' 150 | > let moduleName = node.arguments[0].value 151 | > moduleName = moduleName + (path.extname(moduleName)? '':'.js') 152 | > moduleName = './' + path.join(parentPath,moduleName) //'src/a.js' 153 | > dependencies.push(moduleName) 154 | > //节点替换 155 | > node.arguments = [types.StringLiteral(moduleName)] 156 | > } 157 | > } 158 | > }) 159 | > let sourceCode = generator(ast).code 160 | > return {sourceCode,dependencies} 161 | > } 162 | > buildModule(modulePath,isEntry){ 163 | > //模块内容 164 | > let source = this.getSource(modulePath) 165 | > // 模块id moduleName = modulePath - this.root // path.relative对应 此方法 166 | > // 这个方法没见到过 记一下 167 | > let moduleName = './' + path.relative(this.root,modulePath) 168 | > if(isEntry) { 169 | > this.entryId = moduleName // 保存入口名字 170 | > } 171 | > 172 | > // 解析 需要把source源码进行改造 返回一个依赖列表 173 | > let {sourceCode,dependencies} = this.parse(source,path.dirname(moduleName)) 174 | > // 把相对路径和模块中的内容对应起来 175 | > this.modules[moduleName] = sourceCode 176 | > dependencies.forEach(dep=>{ 177 | > //附模块的加载 递归加载 178 | > this.buildModule(dep,false) 179 | > }) 180 | > } 181 | > emitFile() { //发射文件 182 | > //数据渲染 183 | > //看的是webpack.config.js中的output 184 | > let main = path.join(this.config.output.path,this.config.output.filename) 185 | > //读取模板 186 | > let templateStr = this.getSource(path.join(__dirname,'main.ejs')) 187 | > //渲染 188 | > let code = ejs.render(templateStr,{entryId:this.entryId,modules:this.modules}) 189 | > //拿到输出到哪个目录下 190 | > //资源中 路径对应的代码 191 | > this.assets[main] = code 192 | > fs.writeFileSync(main,this.assets[main]) 193 | > } 194 | > run(){ 195 | > //执行 解析文件依赖 196 | > //执行 并且创建模块依赖关系 197 | > this.hooks.run.call() 198 | > //编译 调用 199 | > this.hooks.compile.call() 200 | > this.buildModule(path.resolve(this.root,this.entry),true) 201 | > // 发射一个文件 打包后的文件 202 | > this.hooks.afterCompile.call() 203 | > this.emitFile() 204 | > this.hooks.emit.call() 205 | > this.hooks.done.call() 206 | > } 207 | > } 208 | > module.exports = Compiler 209 | > ``` 210 | > 211 | > 212 | 213 | ## webpack.config.js 214 | 215 | > ```js 216 | > const path = require('path') 217 | > //模拟插件 218 | > class P{ 219 | > apply(compiler){ 220 | > //发射 订阅 221 | > compiler.hooks.emit.tap('emit',()=>{ 222 | > console.log('emit事件') 223 | > }) 224 | > } 225 | > } 226 | > class P1{ 227 | > apply(compiler){ 228 | > //发射 订阅 229 | > compiler.hooks.afterPlugins.tap('emit',()=>{ 230 | > console.log('afterPlugins') 231 | > }) 232 | > } 233 | > } 234 | > module.exports = { 235 | > mode: 'development', 236 | > entry: './src/index.js', 237 | > output:{ 238 | > filename: 'bundle.js', 239 | > path: path.resolve(__dirname,'dist') 240 | > }, 241 | > module:{ 242 | > rules:[ 243 | > { 244 | > test: /\.less$/, 245 | > use:[ 246 | > path.resolve(__dirname,'loader','style-loader'), 247 | > path.resolve(__dirname,'loader','less-loader') 248 | > ] 249 | > } 250 | > ] 251 | > }, 252 | > plugins:[ 253 | > new P(), 254 | > new P1() 255 | > ] 256 | > } 257 | > ``` 258 | > 259 | > 260 | 261 | ## less-loader.js 262 | 263 | > ```js 264 | > let less = require('less') 265 | > let css = '' 266 | > function loader(source){ 267 | > less.render(source,(error,c)=>{ 268 | > css = c.css 269 | > }) 270 | > //正则 将/n替换成//n 不然会被当做转义字符来处理 不换行 271 | > css = css.replace(/\n/g,'\\n') 272 | > return css 273 | > } 274 | > module.exports = loader 275 | > ``` 276 | > 277 | > 278 | 279 | ## style-loader.js 280 | 281 | > ```js 282 | > let style = '' 283 | > function loader(source){ 284 | > style = `let style = document.createElement('style') 285 | > style.innerHTML = ${JSON.stringify(source)} 286 | > document.head.appendChild(style)` 287 | > return style 288 | > 289 | > //style.innerHTML = JSON.stringify(loader) 可以将index.less的代码转为一行 290 | > } 291 | > 292 | > module.exports = loader 293 | > ``` 294 | > 295 | > 296 | 297 | ## main.ejs 298 | 299 | > ```ejs 300 | > (function(modules) { // webpackBootstrap webpack入口函数 301 | > var installedModules = {}; 302 | > function __webpack_require__(moduleId) { 303 | > if(installedModules[moduleId]) { 304 | > return installedModules[moduleId].exports; 305 | > } 306 | > var module = installedModules[moduleId] = { 307 | > i: moduleId, 308 | > l: false, 309 | > exports: {} 310 | > }; 311 | > modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 312 | > return module.exports; 313 | > } 314 | > return __webpack_require__(__webpack_require__.s = "<%-entryId%>");//入口模块 315 | > }) 316 | > 317 | > ({ 318 | > <%for(let key in modules) {%> 319 | > "<%-key%>": //key->模块的路径 320 | > (function(module, exports,__webpack_require__) { 321 | > eval(`<%-modules[key]%>`); 322 | > }), 323 | > <%}%> 324 | > }); 325 | > ``` 326 | > 327 | > -------------------------------------------------------------------------------- /webpack笔记/webpack学习...06.md: -------------------------------------------------------------------------------- 1 | ## webpack学习...06 2 | 3 | ## 安装 4 | 5 | > ```shell 6 | > #提前安装 7 | > cnpm i webpack webpack-cli -D 8 | > #安装 @babel/core @babel/preset-env来测试 babel-loader 9 | > cnpm i @babel/core @babel/preset-env 10 | > #安装 loader-utils 来 11 | > cnpm i loader-utils 12 | > #安装 schema-utils 骨架校验 13 | > 安装 mime 来解析文件后缀名 14 | > #安装 less 来解析less语法 15 | > ``` 16 | > 17 | > 18 | 19 | ## loader配置的三种方式 20 | 21 | > ```js 22 | > use:[//找loader1的第一种方式 23 | > // path.resolve(__dirname,'loader','loader1.js') 24 | > 'loader1'] 25 | > resolveLoader:{ 26 | > //第三种方法 配置modules 默认去node_modules下找 找不到去loader文件夹下找 27 | > modules:['node_modules',path.resolve(__dirname,'loader')] 28 | > /* // //第二种方法 配置 loader别名 29 | > alias:{ 30 | > 'loader1':path.resolve(__dirname,'loader','loader1.js') 31 | > } */ 32 | > 33 | > } 34 | > ``` 35 | > 36 | > 37 | 38 | ## loader顺序以及分类 39 | 40 | > ```js 41 | > // loader默认从下到上,从右到左执行 42 | > // loader的分类 pre 之前 post 之后 normal 正常(默认) 43 | > // loader的标准顺序 pre normal inline(行内) post 44 | > 45 | > // loader 由两部分组成 pitch-loader normal-loader 46 | > 47 | > { 48 | > test: /\.js$/, 49 | > use: 'loader1', 50 | > enforce: 'pre' 51 | > } 52 | > { 53 | > test: /\.js$/, 54 | > use: 'loader2', 55 | > enforce: 56 | > } 57 | > { 58 | > test: /\.js$/, 59 | > use: 'loader3', 60 | > enforce: 'post' 61 | > } 62 | > 63 | > //inline-loader处理 64 | > //inline-loader! 这样会运行inline-loader 65 | > // -!不会通过 pre normal来处理了 66 | > // !没有normal 67 | > // !!什么都不要 只用inline-loader (这样会运行完post(之前的先走完) 再运行inline) 68 | > require('inline-loader!./a.js') 69 | > ``` 70 | > 71 | > 72 | 73 | ## loader的组成 74 | 75 | > ```js 76 | > //pitch 无返回值 77 | > pitch loader3 → loader2 → loader1 78 | > ↘ 79 | > 资源 80 | > ↙ 81 | > normal loader3 ← loader2 ← loader1 82 | > //有返回值 83 | > user: [loader3, loader2, loader1] 84 | > // pitch loader - 有返回值 85 | > pitch loader3 → loader2 loader1 86 | > ↙ 87 | > 有返回值 资源 88 | > ↙ 89 | > normal loader3 loader2 loader1 90 | > 91 | > //loader2.js 92 | > function loader(source){ //loader的参数就是源代码 93 | > console.log(2) 94 | > return source; 95 | > } 96 | > loader.pitch = function(){ 97 | > return 'ok' 98 | > } 99 | > module.exports = loader 100 | > 101 | > //这样运行 只会返回3 102 | > ``` 103 | > 104 | > 105 | 106 | ## babel-loader.js 107 | 108 | > ```js 109 | > let babel = require("@babel/core"); 110 | > //loaderUtils 拿到预设 便于后期转化代码 111 | > let loaderUtils = require("loader-utils"); 112 | > function loader(source) { // this loaderContext 113 | > //Object.keys方法 属性转成一个数组 114 | > let options = loaderUtils.getOptions(this); 115 | > // console.log(this.resourcePath) 运行时返回一个绝对路径 116 | > //console.log(options); 117 | > // options 打印为{ presets: [ '@babel/preset-env' ] } 118 | > let cb = this.async() // loader上下文 默认有async这个方法 异步执行 在哪执行调用cb就可以 119 | > //babel的transform有三个参数 第一个 转换哪些代码 第二个 转换选项 第三个 异步回调函数 120 | > babel.transform(source,{ 121 | > ...options, //对象展开 122 | > sourceMap: true, //调试工具 需要webpack.config.js 也要配置 source-map 123 | > filename: this.resourcePath.split('/').pop()//文件名 不然运行时 webpack下边是unkown 124 | > 125 | > },function(err,result){ 126 | > //异步回调 return source就不起作用了 127 | > cb(err,result.code,result.map) // 异步 cb(123) 会错误 必须严格按照参数来 128 | > // 第一个 错误 第二个 代码 第三个 sourceMap 129 | > }) 130 | > // return source; 不起作用 131 | > } 132 | > module.exports = loader; 133 | > ``` 134 | > 135 | > 136 | 137 | ## banner-loader.js 138 | 139 | > ```js 140 | > let loaderUtils = require('loader-utils') 141 | > //骨架校验 142 | > let validateOptions = require('schema-utils') 143 | > //读取文件模块 144 | > let fs = require('fs') 145 | > function loader(source){ 146 | > this.cacheable && this.cacheable() //一般这样用 147 | > //this.cacheable(false) //缓存 自动缓存 148 | > let options = loaderUtils.getOptions(this) 149 | > let cb = this.async() //异步必备 150 | > let schema = { 151 | > type: 'object', 152 | > properties: { 153 | > text: { 154 | > type: 'string', 155 | > 156 | > }, 157 | > filename: { 158 | > type: 'string' 159 | > } 160 | > } 161 | > } 162 | > //将骨架和参数对比 'banner-loader'出问题(如果报错) 163 | > validateOptions(schema,options,'banner-loader') 164 | > if(options.filename){ 165 | > this.addDependency(options.filename) //自动地 添加文件依赖 加入这一句话 开启实时监控 webpack也会监控这个文件 这个文件更新也会实时更新 166 | > fs.readFile(options.filename,'utf-8',function(err,data){ 167 | > cb(err,`/**${data}**/${source}`) 168 | > }) 169 | > }else { 170 | > //同步也得 cb调用了 171 | > cb(null,`/**${options.text}**/${source}`) 172 | > } 173 | > // return source 又是异步 需要创建一个cb 174 | > } 175 | > module.exports = loader 176 | > ``` 177 | > 178 | > 179 | 180 | ## less-loader.js 181 | 182 | > ```js 183 | > let less = require('less') 184 | > console.log(less) 185 | > function loader(source) { 186 | > let css 187 | > less.render(source,(err,r) => { 188 | > css = r.css 189 | > }) 190 | > return css 191 | > } 192 | > 193 | > module.exports = loader 194 | > ``` 195 | > 196 | > 197 | 198 | ## style-loader.js 199 | 200 | > ```js 201 | > let style = '' 202 | > function loader(source) { 203 | > return `style = document.createElement('style') 204 | > style.innerHTML = ${JSON.stringify(source)} 205 | > document.head.appendChild(style)` 206 | > } 207 | > module.exports = loader 208 | > ``` 209 | > 210 | > 211 | 212 | ## css-loader.js 213 | 214 | > ```js 215 | > function loader(source) { 216 | > let reg = /url\((.+?)\)/g 217 | > //第一次查找肯定是从零开始查找 218 | > let pos = 0 219 | > let arr = ['let list = []'] 220 | > while(current = reg.exec(source)) { 221 | > let [matchUrl,g] = current 222 | > //reg.lastIndex 对应着匹配最后一个字符的长度 matchUrl对应着url('./lala.jpg')的长度 223 | > //相减可以得到前边的不包含 url的值 224 | > let last = reg.lastIndex - matchUrl.length 225 | > arr.push(`list.push(${JSON.stringify(source.slice(pos,last))})`) 226 | > //把 g 替换成ruquire的写法 227 | > arr.push(`list.push('url('+ require(${g}) +')')`) 228 | > pos = reg.lastIndex 229 | > // 添加后边的 230 | > arr.push(`list.push(${JSON.stringify(source.slice(pos))})`) 231 | > arr.push(`module.exports = list.join(' ')`) 232 | > return arr.join('\r\n') 233 | > } 234 | > return source 235 | > } 236 | > module.exports = loader 237 | > ``` 238 | > 239 | > 240 | 241 | ## webpack.config.js 242 | 243 | > ```js 244 | > let path = require("path"); 245 | > module.exports = { 246 | > mode: "development", 247 | > entry: "./src/index.js", 248 | > output: { 249 | > filename: "build.js", 250 | > path: path.resolve(__dirname, "dist") 251 | > }, 252 | > 253 | > resolveLoader: { 254 | > //第三种方法 配置modules 默认去node_modules下找 找不到去loader文件夹下找 255 | > modules: ["node_modules", path.resolve(__dirname, "loader")] 256 | > /* // //第二种方法 配置 loader别名配置别名 257 | > alias:{ 258 | > 'loader1':path.resolve(__dirname,'loader','loader1.js') 259 | > } */ 260 | > }, 261 | > devtool:'source-map', 262 | > // watch:true, 263 | > module: { 264 | > rules:[ 265 | > { 266 | > test: /\.less$/, 267 | > use:[ 268 | > 'style-loader', 269 | > 'css-loader', 270 | > 'less-loader' 271 | > ] 272 | > }, 273 | > { 274 | > test: /\.jpg$/, 275 | > // 目的 根据图片生成一个 md5串 发射到dist目录下 file-loader还会返回当前路径 276 | > /* use:{ 277 | > loader: 'file-loader', 278 | > } */ 279 | > use:{ //符号中文 会报Invalid or unexpected token 280 | > loader: 'url-loader', //url-loader会处理路径并且交给file-loader 281 | > options:{ 282 | > limit: 200*1024 283 | > } 284 | > } 285 | > } 286 | > /* { 287 | > test: /\.js$/, 288 | > use:{ 289 | > loader: 'banner-loader', 290 | > options:{ 291 | > text: 'hanke', 292 | > //如果没有给text的时候 293 | > filename: path.resolve(__dirname,'banner.js') 294 | > } 295 | > } 296 | > } */ 297 | > /* { 298 | > test: /\.js$/, 299 | > use:{ 300 | > loader: 'babel-loader', 301 | > options:{ 302 | > presets: [ 303 | > '@babel/preset-env' 304 | > ] 305 | > } 306 | > } 307 | > } */ 308 | > ] 309 | > // rules: [ 310 | > // /* { 311 | > // test: /\.js$/, 312 | > // use:[ 313 | > // //找loader1的几种方式 314 | > // // path.resolve(__dirname,'loader','loader1.js') 315 | > // 'loader3','loader2','loader1' 316 | > // //从右到左 从下到上执行 317 | > // ] 318 | > // } */ 319 | > // { 320 | > // test: /\.js$/, 321 | > // use: "loader1", 322 | > // enforce: "pre" 323 | > // }, 324 | > // { 325 | > // test: /\.js$/, 326 | > // use: "loader2" 327 | > // }, 328 | > // { 329 | > // test: /\.js$/, 330 | > // use: "loader3", 331 | > // enforce: "post" 332 | > // } 333 | > // ] 334 | > } 335 | > }; 336 | > 337 | > ``` 338 | > 339 | > 340 | 341 | -------------------------------------------------------------------------------- /webpack笔记/webpack学习...07.md: -------------------------------------------------------------------------------- 1 | ## webpack学习...07 2 | 3 | ## 安装 4 | 5 | > ```shell 6 | > # 初始安装 7 | > cnpm i webpack webpack-cli -D 8 | > # 安装 html-webpack-plugin 来测试文件插件 9 | > cnpm i html-webpack-plugin -D 10 | > # 安装 css-loader mini-css-extract-loader -D 来测试 内联 11 | > cnpm i css-loader mini-css-extract-plugin -D 12 | > # 安装七牛来测试上传文件 13 | > cnpm i qiniu 14 | > # 安装最新版 html-webpack-plugin@next来阅读文档 测试 内联 15 | > cnpm i html-webpack-plugin@next -D 16 | > ``` 17 | > 18 | > 19 | 20 | ## webpack如何调用plugin 21 | 22 | > node_modules下的webpack下的lib中的Compiler.js 23 | > 24 | > ```js 25 | > //node_modules下的webpack下的lib中的compile.js 26 | > // 有一些钩子 27 | > const childCompiler = new Compiler(this.context); 28 | > if (Array.isArray(plugins)) { 29 | > for (const plugin of plugins) { 30 | > plugin.apply(childCompiler); 31 | > } 32 | > } 33 | > ``` 34 | > 35 | > 36 | 37 | ## DonePlugin.js 38 | 39 | > ```js 40 | > class DonePlugin{ 41 | > apply(compiler) // compiler.hooks 42 | > { 43 | > //这样是一个同步代码 44 | > console.log(1) 45 | > //第一个参数无所谓,放啥都可以 tapable的时候也是 46 | > compiler.hooks.done.tap('DonePlugin',(states)=>{ 47 | > console.log('编译完成哦哦哦') 48 | > }) 49 | > } 50 | > } 51 | > //还需要导出一下 52 | > module.exports = DonePlugin 53 | > ``` 54 | > 55 | > 56 | 57 | ## AsyncPlugin.js 58 | 59 | > ```js 60 | > class AsyncPlugin { 61 | > 62 | > apply(compiler){ 63 | > //这样是一个同步代码 64 | > console.log(2) 65 | > compiler.hooks.emit.tapAsync('AsyncPlugin',(compliation,cb)=>{ 66 | > setTimeout(()=>{ 67 | > console.log('等一下') 68 | > cb() 69 | > },1000) 70 | > }) 71 | > compiler.hooks.emit.tapPromise('AsyncPlugin',(compliation)=>{ 72 | > return new Promise((resolve,reject)=>{ 73 | > setTimeout(()=>{ 74 | > console.log('再等一下') 75 | > resolve() 76 | > },1000) 77 | > }) 78 | > }) 79 | > } 80 | > } 81 | > module.exports = AsyncPlugin 82 | > ``` 83 | > 84 | > 85 | 86 | ## InlineSourcePlugin.js 87 | 88 | > ```js 89 | > const HtmlWebpackPlugin = require('html-webpack-plugin'); 90 | > //把外链标签变成内联 91 | > class InlineSourcePlugin{ 92 | > constructor({test}){ 93 | > this.reg = test //正则 94 | > } 95 | > processTag(tag,compilation) { 96 | > let newTag,url 97 | > if(tag.tagName==='link'&&this.reg.test(tag.attributes.href)){ 98 | > newTag = { 99 | > tagName: 'style', 100 | > attributes: { 101 | > type: 'text/css' 102 | > } 103 | > } 104 | > url = tag.attributes.href 105 | > }else if(tag.tagName==='script'&&this.reg.test(tag.attributes.src)){ 106 | > newTag = { 107 | > tagName: 'script', 108 | > attributes: { 109 | > type: 'application/javascript' 110 | > } 111 | > } 112 | > url = tag.attributes.src 113 | > } 114 | > if(url){ 115 | > newTag.innerHTML = compilation.assets[url].source() //文件内容 116 | > //删除这一个资源 117 | > delete compilation.assets[url] 118 | > return newTag 119 | > } 120 | > return tag 121 | > } 122 | > processTags(data,compilation){ 123 | > let bodyTags = [] 124 | > let headTags = [] 125 | > data.headTags.forEach(headTag => { 126 | > headTags.push(this.processTag(headTag,compilation)) 127 | > }) 128 | > data.bodyTags.forEach(bodyTag => { 129 | > bodyTags.push(this.processTag(bodyTag,compilation)) 130 | > }) 131 | > return {...data,headTags,bodyTags} 132 | > } 133 | > apply(compiler){ 134 | > //要通过 HtmlWebpackPlugin的钩子来实现这一功能 根据官网文档修改 135 | > compiler.hooks.compilation.tap('InlineSourcePlugin', (compilation) => { 136 | > HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync( 137 | > 'AfterPlugin', 138 | > (data, cb) => { 139 | > //将link变成内联 script变成内联 140 | > data = this.processTags(data,compilation) //compilation.assets 资源 141 | > cb(null, data) 142 | > } 143 | > ) 144 | > }) 145 | > } 146 | > } 147 | > 148 | > module.exports = InlineSourcePlugin 149 | > ``` 150 | > 151 | > 152 | 153 | ## webpack.config.js 154 | 155 | > ```js 156 | > let path = require('path') 157 | > /* let DonePlugin = require('./plugins/DonePlugin.js') 158 | > let AsyncPlugin = require('./plugins/AsyncPlugin.js') */ 159 | > let HtmlWebpackPlugin = require('html-webpack-plugin') 160 | > let FileListPlugin = require('./plugins/FileListPlugin') 161 | > let MiniCssExtractPlugin = require('mini-css-extract-plugin') 162 | > let InlineSourcePlugin = require('./plugins/InlineSourcePlugin') 163 | > module.exports = { 164 | > mode: 'development', 165 | > entry: './src/index.js', 166 | > output:{ 167 | > filename: 'bundle.js', 168 | > path: path.resolve(__dirname,'dist') 169 | > }, 170 | > module:{ 171 | > rules:[ 172 | > { 173 | > test: /\.css$/, 174 | > use: [MiniCssExtractPlugin.loader,'css-loader'] 175 | > } 176 | > ] 177 | > }, 178 | > plugins:[ 179 | > /* new DonePlugin(), 180 | > new AsyncPlugin() */ 181 | > new HtmlWebpackPlugin({ 182 | > template: './src/index.html' 183 | > }), 184 | > /* new FileListPlugin({ 185 | > filename: 'list.md' 186 | > }), */ 187 | > new MiniCssExtractPlugin({ 188 | > filename: 'main.css' 189 | > }), 190 | > new InlineSourcePlugin({ 191 | > test: /(\.js|css)/ 192 | > }) 193 | > ] 194 | > } 195 | > ``` 196 | > 197 | > --------------------------------------------------------------------------------