{"id":18428185,"url":"https://github.com/futurewan/webpack-practice","last_synced_at":"2025-04-13T20:54:34.792Z","repository":{"id":134471632,"uuid":"96995907","full_name":"futurewan/webpack-practice","owner":"futurewan","description":null,"archived":false,"fork":false,"pushed_at":"2018-03-18T09:24:10.000Z","size":10142,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-13T20:54:24.442Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/futurewan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-12T10:33:42.000Z","updated_at":"2018-03-18T09:24:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"d77453f3-722b-48e8-93b2-533bf0153c45","html_url":"https://github.com/futurewan/webpack-practice","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futurewan%2Fwebpack-practice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futurewan%2Fwebpack-practice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futurewan%2Fwebpack-practice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/futurewan%2Fwebpack-practice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/futurewan","download_url":"https://codeload.github.com/futurewan/webpack-practice/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248782281,"owners_count":21160716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T05:13:00.801Z","updated_at":"2025-04-13T20:54:34.771Z","avatar_url":"https://github.com/futurewan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## webpack构建流程\n从启动webpack构建到输出结果经历了一系列过程，它们是：\n1. 解析webpack配置参数，合并从shell传入和webpack.config.js文件里配置的参数，生产最后的配置结果。\n2. 注册所有配置的插件，好让插件监听webpack构建生命周期的事件节点，以做出对应的反应。\n3. 从配置的entry入口文件开始解析文件构建AST语法树，找出每个文件所依赖的文件，递归下去。\n4. 在解析文件递归的过程中根据文件类型和loader配置找出合适的loader用来对文件进行转换。\n5. 递归完后得到每个文件的最终结果，根据entry配置生成代码块chunk。\n6. 输出所有chunk到文件系统。\n\n\n## 入口(entry)\n\u003e 指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始\n\n### 对象语法\n- 分离 应用程序(app) 和 第三方库(vendor) 入口\n```\n  entry: {\n    app: './src/app.js',\n    vendors: './src/vendors.js'\n  }\n```\n这告诉我们 webpack 从 app.js 和 vendors.js 开始创建依赖图(dependency graph)。这些依赖图是彼此完全分离、互相独立的\n\n\n## 出口(output)\n\u003e 告诉 webpack 在哪里输出它所创建的 bundles\n\n\n\n\n## loader\n\u003e loader 让 webpack 能够去处理那些非 JavaScript 文件（webpack 自身只理解 JavaScript）\nmodule.loaders 改为 module.rules\n链式loader\nwebpack1语法\n```\nmodule: {\n    loaders: [{\n        test: /\\.less$/,\n        loader: \"style-loader!css-loader!less-loader\"\n    })\n}\n```\nwebpack2、3语法\n```\nmodule: {\n    rules: [{\n        test: /\\.less$/,\n        use: [\n            \"style-loader\",\n            \"css-loader\",\n            \"less-loader\"\n        ]\n    }]\n}\n```\n\n### 文件\n#### raw-loader 加载文件原始内容，比如txt\n#### file-loader 将文件发送到打包后文件夹中\n#### url-loader 功能类似file-loader可以设置小图片转换base64图片\n```\n{\n    test: /\\.(png|jpg|gif)$/,\n        use: [\n        {\n            loader: 'file-loader',\n            options: {}\n        }\n    ]\n}\n```\n\n### style-loader css代码放入js代码里再加入到html里\n### css-loader 读取css文件\n### postcss\n后处理css文件，对css文件做语法分析，真正的核心操作，依赖于postcss庞大的插件群体\n[postcss]:https://github.com/postcss/postcss/blob/master/docs/plugins.md\n\u003e 比如css的语法验证，压缩，支持变量和混入语法\n\n#### autoprefixer 补全浏览器前缀\n#### postcss-import\ncss文件中使用@import引入其他样式文件，但是使用autoprefixer发现，import进来的样式没有处理\n```\npostcss: function(webpack) {\n  return [\n    postcssImport({\n      addDependencyTo: webpack\n    }),\n    autoprefixer\n  ]\n}\n```\n### less-loader sass-loader 编译为css文件\n\n\n\n## 插件\n\u003e loader 被用于转换某些类型的模块，而插件则可以用于执行范围更广的任务。插件的范围包括，从打包优化和压缩，一直到重新定义环境中的变量\n\n### html-webpack-plugin 生成html文件\n- 为html文件中引入的外部资源如script、link动态添加每次compile后的hash，防止引用缓存的外部文件问题\n- 可以生成创建html入口文件，比如单页面可以生成一个html文件入口，配置N个html-webpack-plugin可以生成N个页面入口\n\n\n\n### extract-text-webpack-plugin\nwebpack 把所有的资源都当成了一个模块, CSS,Image, JS 字体文件资源, 都打包到一个 bundle.js 文件中\nwebpack单独打包css\n配置：\n```\nconst ExtractTextPlugin = require('extract-text-webpack-plugin')\nmodule: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: ExtractTextPlugin.extract({\n          fallback: \"style-loader\", //编译后用什么loader来提取css文件\n          use: \"css-loader\" //需要什么样的loader去编译文件\n        })\n      }\n    ]\n  }\n```\npublicfile //用来覆盖项目路径,生成该css文件的文件路径\n\n`new ExtractTextPlugin([id: string], filename: string, [options])`\n1.id该插件实例的唯一标志，一般是不会传的，其自己会生成。\n2.filename文件名。可以是[name]、[id]、[contenthash]\n\t[name]：将会和entry中的chunk的名字一致\n\t[id]：将会和entry中的chunk的id一致\n\t[contenthash]：根据内容生成hash值\n3.options\n\tallchunk： 是否将所有额外的chunk都压缩成一个文件\n\tdisable：禁止使用插件\n\n### CopyWebpackPlugin 拷贝资源插件\n```\nCopyWebpackPlugin([\n        {\n            context: 'global/img',\n            from: '**/*',\n            to:'img/common'\n        },\n        {\n            from: 'img',\n            to:'img'\n        },\n        {\n            from :'global/lib/es5-shim-sham.js'\n        }\n])\n```\nfrom 定义要拷贝的源目录.   \nto 定义要拷盘的目标目录.   \ncontext 上下文.   \nflatten 只拷贝文件不管文件夹 默认是false.   \nignore 忽略拷贝指定的文件 可以用模糊匹配.   \nforce 强制覆盖先前的插件 可选 默认false.   \n\n\n### cross-env\n在不同系统环境下设置变量\n\n\n### webpack-dev-server\n* 开发环境用于调试报错信息等,生成一个开发用的服务器，在文件有变化的时候自动给我们打包，然后刷新页面\n* 它还有个模块热替换的功能 .. 就是它可以只替换有变化的地方 .. 不需要刷新整个页面 ... \n\n\n### webpack自带插件\n#### UglifyJsPlugin 压缩js css文件\n```\nnew webpack.optimize.UglifyJsPlugin({\n    compress: {\n      warnings: false\n    }\n  })\n```\n`Unexpected token: operator (\u003e) from UglifyJs`问题可以使用 uglifyjs-webpack-plugin插件\n\n\n#### CommonsChunkPlugin 提取 chunks 之间共享的通用模块\nwebpack将多个模块打包之后的代码集合称为chunk\nwebpack打包的代码都是以chunk的形式存储的\n- 是一个可选的用于建立一个独立文件(又称作 chunk)的功能\n- 通过将公共模块拆出来，最终合成的文件能够在最开始的时候加载一次，便存到缓存中供后续使用\n- 语法：\nnew webpack.optimize.CommonsChunkPlugin(options)\n- 配置\n1. 决定生成chunk的参数: name, names, async\n- name: string: 公共chunk的名字\n- names: string[]: 和name一样，不过传入的是一个数组\n- async: boolean|string: 把公共代码提取到一个懒加载的chunk，在被使用到时才进行下载\n2. 决定被提取的chunk: chunks, children, deepChildren\n3. 决定提取条件: minChunks\n- minChunks: number|infinity|function(module,count)-\u003eboolean: 如果传入数字或infinity(默认值为3)，就是告诉webpack，只有当模块重复的次数大于等于该数字时，这个模块才会被提取出来。当传入为函数时，所有符合条件的chunk中的模块都会被传入该函数做计算，返回true的模块会被提取到目标chunk\n\n\n### HotModuleReplacementPlugin 热模块替换\n```\nnew webpack.HotModuleReplacementPlugin()\n```\n\n```\ndevServer: {\n    hot: true // 激活服务器的HMR\n}\n```\n\n\n\n\n\n#### DefinePlugin 允许在编译时(compile time)配置的全局常量\n\n\n*******\n## 优化\n### 优化输出\n#### 压缩css\n`css-loader?minimize`去除css文件里有很多空格和tab\n#### tree-shaking\n借助es6 `import export`语法静态性的特点来删掉export但是没有import过的东西\n- 配置babel让它在编译转化es6代码时不把import export转换为cmd的module.export，配置如下：\n```\n\"presets\": [\n    [\n      \"es2015\",\n      {\n        \"modules\": false\n      }\n    ]\n]\n```\n\n#### 优化 UglifyJsPlugin\n```\nnew UglifyJsPlugin({\n    // 最紧凑的输出\n    beautify: false,\n    // 删除所有的注释\n    comments: false,\n    compress: {\n      // 在UglifyJs删除没有用到的代码时不输出警告  \n      warnings: false,\n      // 删除所有的 `console` 语句\n      // 还可以兼容ie浏览器\n      drop_console: true,\n      // 内嵌定义了但是只用到一次的变量\n      collapse_vars: true,\n      // 提取出出现多次但是没有定义成变量去引用的静态值\n      reduce_vars: true,\n    }\n})\n```\n#### 用`imagemin-webpack-plugin`压缩图片\n\n### 更快的构建\n#### 缩小文件搜索范围\n- 配置模块库.   \n在js里出现import 'redux'这样不是相对也不是绝对路径的写法时会去node_modules目录下找。但是默认的配置会采用向上递归搜索的方式去寻找node_modules，但通常项目目录里只有一个node_modules在项目根目录 \n```\nmodule.exports = {\n    resolve: {\n        modules: [path.resolve(__dirname, 'node_modules')]\n    }\n};\n```\n- 配置loader\n```\n{\n    test: /\\.js$/,\n    loader: 'babel-loader',\n    include: path.resolve(__dirname, 'src')\n}\n```\n\n#### 开启 babel-loader 缓存\nbabel编译过程很耗时，好在babel-loader提供缓存编译结果选项，在重启webpack时不需要创新编译而是复用缓存结果减少编译流程。babel-loader缓存机制默认是关闭的，打开的配置如下：   \n```\n{\ntest: /\\.js$/,\n      loader: 'babel-loader?cacheDirectory',\n}\n```\n#### 使用 alias\nresolve.alias 配置路径映射。\n发布到npm的库大多数都包含两个目录，一个是放着cmd模块化的lib目录，一个是把所有文件合成一个文件的dist目录，多数的入口文件是指向lib里面下的。   \n默认情况下webpack会去读lib目录下的入口文件再去递归加载其它依赖的文件这个过程很耗时，alias配置可以让webpack直接使用dist目录的整体文件减少文件递归解析。配置如下：\n```\nmodule.exports = {\n  resolve: {\n    alias: {\n      'moment': 'moment/min/moment.min.js',\n      'react': 'react/dist/react.js',\n      'react-dom': 'react-dom/dist/react-dom.js'\n    }\n  }\n};\n```\n#### 使用 noParse\n`module.noParse` 配置哪些文件可以脱离webpack的解析。\n有些库是自成一体不依赖其他库的没有使用模块化的，比如jquey、momentjs、chart.js，要使用它们必须整体全部引入。   \nwebpack是模块化打包工具完全没有必要去解析这些文件的依赖，因为它们都不依赖其它文件体积也很庞大，要忽略它们配置如下：\n```\nmodule.exports = {\n  module: {\n    noParse: /node_modules\\/(jquey|moment|chart\\.js)/\n  }\n};\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuturewan%2Fwebpack-practice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffuturewan%2Fwebpack-practice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuturewan%2Fwebpack-practice/lists"}