webpack | 青训营笔记

58 阅读5分钟
webpack可以做的事情
  • 代码转换
  • 文件优化
  • 代码分隔
  • 模块合并
  • 自动刷新
  • 代码校验
  • 自动发布
用到的知识
  • node基础
  • npm用法
  • ES6语法
学习范围
  • webpack常见配置
  • webpack高级配置
  • webpack优化策略
  • ast抽象语法树
  • webpack中的Tapable
  • webpack的常用loader
  • webpack常用plugin
webpack基础配置
  • webpack 本地安装

  • webpack-cli -D,dev环境安装

  • webpack.config.js ,默认配置文件名(根目录)

  • 一些基础参数配置

    // webpack.config.js let path = require('path'); module.export ={ mode: 'development', // 默认两种模式development,production模式 entry: './scr/index.js', // 入口文件 output: { // 出口 filename: 'bundle.js', // 打包后文件名 path: path.resolve(__dirname, 'dist'), // 必须是绝对路径 } }

  • webpack-dev-server

    • 需要先引入开发环境插件 webpack-dev-server -D

    • 执行 npx webpack-dev-server,生成内存中的打包文件

    • 启动一个开发环境的服务

    • 增加一些开发环境的配置

      module.export = { "devServer": { // 本地服务的端口号 port: 3000, // 默认是127.0.0.1,如果想让其它设备局域网设备访问本地服务,可配置0.0.0.0 host: '0.0.0.0', // 打包时是否显示进度条 progress: true, // 指定服务器资源的根目录根目录 contentBase: './build', // 该配置项可以在HTTP响应中注入一些HTTP响应头。 比如如下:,会加载Response Headers headers: { 'X-foo': '112233' }, // 默认行为是在发现源代码被更新后通过自动刷新整个页面来做到实时预览的,但是开启模块热替换功能后,它是通过在不刷新整个页面的情况下通过使用新模块替换旧模块来做到实时预览的。 hot: true, // 默认行为是在发现源代码被更新后通过自动刷新整个页面来做到实时预览的,但是开启模块热替换功能后,它是通过在不刷新整个页面的情况下通过使用新模块替换旧模块来做到实时预览的。 // 构建且第一次启动时,是否打开浏览器 open: true, // 编译出错时是否在浏览器上显示错误信息 overlay: true, // 代理 proxy: { '/api': { target: 'news.baidu.com', // 目标接口的域名 // secure: true, // https 的时候 使用该参数 changeOrigin: true, // 是否跨域 pathRewrite: { '^/api' : '' // 重写路径 } } } } }

html插件html-webpack-plugin,复制html

let HtmlWebpackPlugin = require('html-webpack-plugin')
module.export = {
  // plugins放所有webpack插件,是个数组,每一项时个类
  plugins: [
    //把output打包文件(bundle.js)塞到html中,同时把文件放到build下面
    new HtmlWebpackPlugin({
      // 生成html文件的标题
      title: 'samcao',
      // 找到要操作的文件模板
      template: './src/index.html',
      // 打包后的文件名字
      filename: 'index.html',
      // 注入选项,true:默认值,script标签位于html文件的 body 底部, 
      // body:script标签位于html文件的 body 底部(同 true)
      // head:script 标签位于 head 标签内
      // false:不插入生成的 js 文件,只是单纯的生成一个 html 文件
      inject: true,
      // favicon 给生成的 html 文件生成一个 favicon。属性值为 favicon 文件所在的路径名
      favicon: '../xxx/xx.png',      
      minify: {
        //是否对大小写敏感,默认false
            caseSensitive: true,
            
            //是否简写boolean格式的属性如:disabled="disabled" 简写为disabled  默认false
            collapseBooleanAttributes: true,
            
            //是否去除空格,默认false
            collapseWhitespace: true,
            
            //是否压缩html里的css(使用clean-css进行的压缩) 默认值false;
            minifyCSS: true,
            
            //是否压缩html里的js(使用uglify-js进行的压缩)
            minifyJS: true,
            
            //Prevents the escaping of the values of attributes
            preventAttributesEscaping: true,
            
            //是否移除属性的引号 默认false
            removeAttributeQuotes: true,
            
            //是否移除注释 默认false
            removeComments: true,
            
            //从脚本和样式删除的注释 默认false
            removeCommentsFromCDATA: true,
            
            //是否删除空属性,默认false
            removeEmptyAttributes: true,
            
            //  若开启此项,生成的html中没有 body 和 head,html也未闭合
            removeOptionalTags: false, 
            
            //删除多余的属性
            removeRedundantAttributes: true, 
            
            //删除script的类型属性,在h5下面script的type默认值:text/javascript 默认值false
            removeScriptTypeAttributes: true,
            
            //删除style的类型属性, type="text/css" 同上
            removeStyleLinkTypeAttributes: true,
            
            //使用短的文档类型,默认false
            useShortDoctype: true,
            },
      // 给生成的 js 文件一个独特的 hash 值,例如:<script type=text/javascript src=bundle.js?22b9692e22e7be37b57e></script>
      hash: true,
      // cache, 默认是true的,表示内容变化的时候生成一个新的文件。
      cache: true,     
      // chunks, chunks主要用于多入口文件,当你有多个入口文件,那就回编译后生成多个打包后的文件,那么chunks 就能选择你要使用那些js文件
      /** entry: {
             index: path.resolve(__dirname, './src/index.js'),
             devor: path.resolve(__dirname, './src/devor.js'),
             main: path.resolve(__dirname, './src/main.js')
         } 
      **/ 
      // 编译后
      /**
        <script type=text/javascript src="index.js"></script>
        <script type=text/javascript src="main.js"></script>
       **/
       chunks: ['index','main'],
        
       // 需要排除掉的chunks
       excludeChunks: ['devor.js']//和的等等效
    })
  ]
}
  • tree-sharking 只对import引入的有效果,
  • require语法不支持tree-sharking,对require引入的es6模块,会把结果放到default上面
  • scope hosting,作用域提升,webpack中会自动省略一些可以简化的代码

抽取公共代码,可用于单页应用或者多页应用, optimization

const optimization = {
  // 分隔代码块, 替代了老版本(commonChunkPlugin)抽离代码的插件
  splitChunks: {
    // 缓存组
    cacheGroups: {
      // 公共的common模块
      common: {
        chunks: 'initial',
        // 文件超过0个字节
        minSize: 0,
        // 只要公用2次以上就抽离
        minChunks: 2,
      },
      // 抽离第三方模块
      vendor: {
        //  权重,权重大的先抽离出来,没有权重会从上到下执行,先抽离第三个模块
         priority: 1, 
        // 把你抽离出来
        test: /node_modules/,
        chunks: 'initial',
        // 文件超过0个字节
        minSize: 0,
        // 只要公用2次以上就抽离
        minChunks: 2,
      }
    }
  }
}

路由懒加载的实现-依靠import语法(看看相关知识点)

热更新插件

  • new.HotModuleReplacementPlugin(),开启热更新

  • new.NameModulePlugin(), 打印更新的模块路径,告诉我们更新的模块名字

  • 下面方法写在具体的入口文件中

    if(module.hot) { module.hot.accept('./accept', () => { console.log('文件更新了----') }) }