webpack学习笔记

webpack

 

配置

entry

  • 整个项目工程文件的入口点
    • entry: { app: path.resolve(__dirname, 'src/index.js') },
  • 多个入口
    • entry: { admin: './admin/index.js', consumer: './consumer/index.js' },
  • 默认值为 ./src
  • 分离 应用程序(app) 和 第三方库(vendor) 入口

    • const config = { entry: { app: './src/app.js', vendors: './src/vendors.js' } };

      output

  • 解析编译后生成压缩文件路径,以及如何命名这些文件

    • output: { publicPath: '/', filename: 'public/js/[name].[hash:8].js', path: path.resolve(__dirname, 'dist') },
  • 默认值为 ./dist
  • path.resolve是nodeJs里面的方法,可以连接两个相对路径并生成绝对路径
  • path与publicPath
    • path:打包后文件在硬盘中的存储位置。
    • publicPath:打包后浏览器访问服务时的 url 路径(中通用的一部分)
    • publicPath可用于改css中资源请求路径。
  • filename
    • "bundle.js", // string
    • "[name].js", // 用于多个入口点(entry point)(出口点?)
    • "[chunkhash].js", // 用于长效缓存
  • library

    • "MyLibrary" // 导出库(exported library)的名称

      module

  • 主要定义项目中的解析器例如css, jsx, babel等等

  • rules
    • { test: /.jsx?$/, include: [ path.resolve(_dirname, "app") ], exclude: [ path.resolve(_dirname, "app/demo-files") ], loader: "babel-loader", },
    • 每个选项都接收一个正则表达式或字符串
    • test 和 include 具有相同的作用,都是必须匹配选项
    • exclude 是必不匹配选项(优先于 test 和 include)
    • 最佳实践:
      • 只在 test 和 文件名匹配 中使用正则表达式
      • 在 include 和 exclude 中使用绝对路径数组
      • 尽量避免 exclude,更倾向于使用 include
  • loader

    • 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript),loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后就可以利用 webpack 的打包能力,对它们进行处理。
    • npm安装加载
    • 属性
      • test
        • 用于标识出应该被对应的 loader 进行转换的某个或某些文件
      • use
        • 表示进行转换时,应该使用哪个 loader
    • 常用
      • 预处理
        • css-loader 处理css中路径引用等问题
        • style-loader 动态把样式写入css
        • sass-loader scss编译器
        • less-loader less编译器
        • postcss-loader scss再处理
      • js处理
        • babel-loader
        • jsx-loader
      • image-loader
      • url-loader
    • ”-loader”可以省略不写,多个loader之间用“!”连接起来
      • loaders: [ { test: /.css$/, loader: 'style-loader!css-loader' }, { test: /.scss$/, loader: 'style!css!sass?sourceMap'}, ]

        mode

  • 通过选择 development 或 production 之中的一个,来设置 mode 参数

    • module.exports = { mode: 'production' };
  • development
    • 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。
  • production
    • 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin.
  • none

    plugin

  • 插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

  • new HtmlWebpackPlugin
    • 单独生成html文件
  • new BrowserSyncPlugin
    • 使用browser-sync实时刷新页面
  • new webpack.optimize.UglifyJsPlugin
    • 负责压缩JS代码,并控制是否要显示警告
  • new webpack.optimize.DedupePlugin
    • 主要查找相等或近似的模块,避免在最终生成的文件中出现重复的模块,比如可以用它去除依赖中重复的插件。
  • new webpack.optimize.OccurenceOrderPlugin
    • 这个插件为组件和模块分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID,通过分析ID,可以建议降低总文件的大小。
  • new webpack.HotModuleReplacementPlugin
    • 全局开启代码热替换,
  • new ExtractTextPlugin

    • 默认情况下,css是被打包到js中的如果接受不了,我们可以应用这个plugin将css style提取出来。

      resolve

  • 其他解决方案

  • module
    • 用于查找模块的目录
      • modules: [ "node_modules", path.resolve(__dirname, "app") ],
  • extensions
    • 使用的扩展名
      • extensions: [".js", ".json", ".jsx", ".css"],
  • alias

    • 模块别名列表
      • alias: { "module": "new-module", // 起别名:"module" -> "new-module" 和 "module/path/file" -> "new-module/path/file" "module": path.resolve(__dirname, "app/third/module.js"), // 起别名 "module" -> "./app/third/module.js" 和 "module/file" 会导致错误 // 模块别名相对于当前上下文导入 },

        context

  • __dirname, // string(绝对路径!)

  • webpack 的主目录,entry 和 module.rules.loader 选项相对于此目录解析

    externals

  • ["react", /^@angular\//]

  • 不要遵循/打包这些模块,而是在运行时从环境中请求他们

    多种配置导出类型

函数

  • module.exports = function(env, argv) { return { mode: env.production ? 'production' : 'development', devtool: env.production ? 'source-maps' : 'eval', plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: argv['optimize-minimize'] // 只有传入 -p 或 --optimize-minimize }) ] }; };

    promise

  • module.exports = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ entry: './app.js', /* ... */ }) }, 5000) }) }

  • webpack 将运行由配置文件导出的函数,并且等待 Promise 返回。便于需要异步地加载所需的配置变量。

    多个配置对象

  • 导出多个配置对象,对于针对多个构建目标(例如 AMD 和 CommonJS)打包一个 library 非常有用。

  • module.exports = [{ output: { filename: './dist-amd.js', libraryTarget: 'amd' }, entry: './app.js', mode: 'production', }, { output: { filename: './dist-commonjs.js', libraryTarget: 'commonjs' }, entry: './app.js', mode: 'production', }]

    优势

以 commonJS 的形式书写脚本,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。

能被模块化的不仅仅是 JS

开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等

扩展性强,插件机制完善,特别是支持 React 热插拔(见 react-hot-loader )

安装

npm install webpack –save-dev

npm install webpack −g

把依赖写入package.json包: npm init

运行

webpack

webpack –display-error-details

  • 出错时能查阅更详尽的信息

 

webpack.config.js文件解析:

  1 const path = require('path');
  2 const webpack = require('webpack');
  3 const HtmlWebpackPlugin = require('html-webpack-plugin');
  4 const CleanWebpackPlugin = require('clean-webpack-plugin');
  5 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  6 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
  7 const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  8 const config = require('./config');
  9 const theme = require('./theme');
 10 
 11 const { API_ENV } = process.env;
 12 const BASE_URL = config.domains[API_ENV].default;
 13 
 14 module.exports = {
 15     entry: { // 工程入口
 16         app: path.resolve(__dirname, 'src/index.js') // __dirname当前目录
 17     },
 18     mode: 'development', // 模式-开发模式
 19     devtool: 'cheap-module-eval-source-map', // 是否以及如何生成源映射。影响build和rebuild速度。
 20     devServer: {
 21         contentBase: './dist',    // 告诉服务器从哪里提供内容
 22         hot: true,                   // 启用webpack的热模块替换功能
 23         port: 8000,               // 指定用于侦听请求的端口号
 24         host:'0.0.0.0',           // 指定要使用的主机。默认情况下这是localhost。
 25         historyApiFallback: true, // 使用HTML5历史记录API时,index.html可能必须提供该页面以代替任何404回复。通过传递启用此功能
 26         proxy: {                   // 代理 当拥有单独的API后端开发服务器并且希望在同一域上发送API请求时,代理某些URL会很有用
 27             "/api": {
 28                 target: BASE_URL, // 在后端打开的情况下启用代理BASE_URL
 29                 changeOrigin: true,
 30                 pathRewrite: {    // 不想/api传递,重写路径
 31                     "^/api": ""
 32                 }
 33             }
 34         },
 35         inline: true // 实时刷新
 36     },
 37     output: { // 混淆压缩后的文件输出
 38         publicPath: '/', //
 39         filename: 'public/js/[name].[hash:8].js', // 文件名
 40         path: path.resolve(__dirname, 'dist') // 文件位置路径
 41     },
 42     optimization: {
 43         // 分离公共依赖块打包文件
 44         splitChunks: {
 45             chunks: 'all'
 46         }
 47     },
 48     plugins: [ // 插件
 49         new HtmlWebpackPlugin({ // 单独生成HTML文件
 50             template: path.resolve(__dirname, 'public/index.html'), // src文件
 51             filename: 'index.html'// dist文件
 52         }),
 53         new webpack.HotModuleReplacementPlugin()
 54     ],
 55     module: { // 主要定义项目中的解析器例如css, jsx, babel等等,使用loader
 56         rules: [
 57             {
 58                 test: /\.(js|jsx)$/, // 被打包文件-后缀名为js或jsx的文件
 59                 loader: 'babel-loader?cacheDirectory', // 使用babel-loader打包
 60                 include: [
 61                     path.resolve(__dirname, './src/')
 62                 ],
 63                 exclude: /node_modules/,
 64                 options: {
 65                     plugins: [
 66                         [
 67                             'import',
 68                             {
 69                                 libraryName: 'antd-mobile',
 70                                 style: true
 71                             },
 72                             'react-photoswipe'
 73                         ],
 74                         'transform-decorators-legacy'
 75                     ]
 76                 }
 77             },
 78             {
 79                 test: /\.(css|less)$/,
 80                 exclude: /node_modules/,
 81                 use: [ // 对test文件打包之前,先用以下loader转换文件
 82                     {
 83                         loader:'style-loader'
 84                     },
 85                     {
 86                         loader: 'css-loader',
 87                         options: {
 88                             sourceMap: true,
 89                             modules: true,
 90                             localIdentName: "[local]--[hash:base64:5]"
 91                         }
 92                     },
 93                     {
 94                         loader: 'less-loader',
 95                         options: {
 96                             javascriptEnabled: true,
 97                             modifyVars: theme
 98                         }
 99                     }
100                 ]
101             },
102             {
103                 test: /\.(css|less)$/,
104                 include: /node_modules/,
105                 use: [
106                     {
107                         loader:'style-loader'
108                     },
109                     {
110                         loader: 'css-loader'
111                     },
112                     {
113                         loader: 'less-loader',
114                         options: {
115                             javascriptEnabled: true,
116                             modifyVars: theme
117                         }
118                     }
119                 ]
120             },
121             {
122                 test: /\.(png|svg|jpe?g|gif)$/i,
123                 exclude: /node_modules/,
124                 use: [
125                     {
126                         loader: 'file-loader',
127                         options: {
128                             outputPath: 'public/images/',
129                             name: '[name].[hash:8].[ext]'
130                         }
131                     }
154                 ]
155             },
156             {
157                 test: /\.(woff|woff2|eot|ttf|otf)$/,
158                 exclude: /node_modules/,
159                 use: [
160                     'file-loader'
161                 ]
162             }
163         ]
164     },
165     resolve: {
166         alias: { // 依赖 对引用的文件设置别名
167             assets: path.resolve(__dirname, 'src/assets'),
168             images: path.resolve(__dirname, 'src/assets/images'),
169             utils: path.resolve(__dirname, 'src/utils'),
170             pages: path.resolve(__dirname, 'src/pages'),
171             components: path.resolve(__dirname, 'src/components')
172         }
173     }
174 };

 

posted @ 2018-08-16 15:55  朝曦Z  阅读(416)  评论(0编辑  收藏  举报