一波webpack

1.什么是WebPack,为什么要使用它?

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。 为什么要使用webpack:因为源码无法直接在浏览器上运行,必须通过转码后才能运行。


2.常见的构建工具

目前的构建工具:

  1. Npm Script
  2. Grunt
  3. Gulp
  4. Fis3
  5. webpack
  6. Rollup

构建工具需要做哪些事:

  1. 代码转换:将TypeScript编译成JavaScript,将scss,less编译成css等
  2. 文件优化:将js,html,css,图片等压缩
  3. 代码分割:提取多个页面的公共代码,提取首屏不需要执行部分的代码让其异步加载
  4. 自动刷新:监听本地源代码的变化,自动重新构建,刷新浏览器
  5. 代码校验:在代码被提交到仓库前检验代码是否符合规范,以及单元测试是否通过
  6. 自动发布:更新代码后,自动构建出线上发布的代码并传输给发布系统。

2.安装webpack

1. 项目初始化  npm init  //初始化项目生成package.json(engions属性告诉当前项目依赖的node哪个版本,npm依赖的哪个版本)
2.npm install webpack -g      //全局安装
npm install --save-dev webpack 或 npm i -D webpack // 本地安装并保存到package.json的devDependencies

3.使用webpack

1.使用webpack之前要对webpack进行一些配置,webpack默认会调用项目根目录下的webpack.config.js这个文件。(想改变调用文件也可以用config命令)。

2.接下来理解几个基本概念:

  • Entry:入口,webpack执行构建的第一步将从Entry开始
  • output 属性告诉 webpack 在哪里输出它所创建的 bundles
  • Module:模块 在webpack中一切皆模块,一个模块对应一个文件,webpack会从配置的entry中,递归找出所有的依赖的模块
  • loader:模块转换器,用于将模块的原内容按照需求转换成新内容
  • plugin:插件是 wepback 的支柱功能。用于解决loader无法做的事情。

3.说说webpack.config.js里面的一些基本配置还有常用的loader,pliugin,结合一些框架。

4.了解更多的配置


4.webpack一些常用的命令

  1. webpack 最基本的启动webpack命令
  2. webpack -w 提供watch方法,实时进行打包更新
  3. webpack -p 对打包后的文件进行压缩
  4. webpack -d 提供SourceMaps,方便调试
  5. webpack --colors 输出结果带彩色,比如:会用红色显示耗时较长的步骤
  6. webpack --profile 输出性能数据,可以看到每一步的耗时

5.webpack打包流程概括

  • 初始化参数:从配置文件和Shell语句中读取和合并参数,得到最终的参数
  • 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
  • 确定入口:根据配置中的 entry 找出所有的入口文件;
  • 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
  • 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  • 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  • 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

6.webpack的优点

  1. webpack 是以 commonJS 的形式来书写脚本的,但对 AMD/CMD 的支持也很全面,方便旧项目进行。
  2. 开发便捷,能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转base64等。
  3. 扩展性强,插件机制完善,特别是支持 React 热插拔(见 react-hot-loader )的功能让人眼前一亮。
  4. webpack有良好的生态链和维护团队,能提供良好的开发体验并保证质量。

7.最后肯定还是得说一说webpack的优化问题了

  • 缩小查找文件的范围(配置时用exclude和include)
  • 开启打包编译多进程(用HappyPack插件)
  • 提取公共代码(用CommonsChunkPlugin插件来实现)
  • 利用动态链接库(用DllPlugin插件来实现)
  • 启用缓存
  • 使用Tree Shaking(需要注意的是在使用Tree Shaking的前提是,提交给webpack的js代码必须采用了es6的模块化语法,)

8.一些学习webpack的链接

webpack.config.js

const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HappyPack = require('happypack');
//构造出共享进程池,在进程池中包含3个子进程
const happyThreadPool = HappyPack.ThreadPool({size: 3 });
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
//DllReferencePlugin用于在主要的配置文件中引入DllPlugin插件打包好的动态链接库文件
const DllReferencePlugin = require('webpack/lib/DllReferencePlugin');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/assets/',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: [
                        {
                            loader: 'css-loader',
                            options: {
                                minimize: true,
                                sourceMap: true,
                                module: true,
                                localIdentName: '[path][name]---[local]---[hash:base64:5]'
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                sourceMap: true,
                                config: {
                                    path: 'postcss.config.js'  // 这个得在项目根目录创建此文件
                                }
                            }
                        }
                    ],
                }),
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpg|gif)$/,
                use: 'url-loader?limit=8192&name=images/[name].[ext]',
                exclude: /node_modules/
            },
            // {
            //     test: /\.js$/,
            //     use: [
            //         {
            //             loader: 'eslint-loader',
            //             options: {
            //                 emitWarning: true
            //             }
            //         },
            //         {
            //             loader:'babel-loader',
            //         },
            //     ],
            // },
            {
                test: /\.js$/,
                use:['happypack/loader?id=babel'],
                exclude: /node_modules/
            }
        ],

    },
    plugins: [
        new ExtractTextPlugin({
            filename: `css.css`,
        }),
        new HtmlWebpackPlugin({
            title: 'feikaiixn'
        }),
        //告诉webpack使用了哪些动态链接库
        new DllReferencePlugin({
            context:__dirname,
            manifest:require('./dist/react.mainfest.json'),
        }),
        new HappyPack({
            id : 'babel',
            loaders:['babel-loader?cacheDirectory'],
            //threads代表开启几个子进程去处理这一类的文件
            //threads:4
            
            //使用共享进程池中的子进程去处理任务
            threadPool:happyThreadPool,
        })
    ],
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000,
        inline: true,
        open: true,
        // overlay:{
        //     errors:true,
        //     warnings:true
        // }
        cache: false,
    },
    watch:true,
    watchOptions:{
        ignored:/node_modules/,
        //监听变化后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
        aggregateTimeout:300
    },
    //resolve配置如何寻找模块所对应的文件
    resolve: {
        alias: {
            components: './'
        },
        extensions: ['.js', '.json']
    },
    devtool: 'source-map'
}

package.json

{
  "name": "webpack-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dll": "webpack -p --config webpack_dll.config.js --progress --profile --colors",
    "dev": "webpack-dev-server --inline --mode development",
    "build": "webpack --mode production --display-used-exports",
    "linkjs": "eslint ./src"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^8.2.0",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^0.28.11",
    "eslint": "^4.19.1",
    "eslint-loader": "^2.0.0",
    "eslint-plugin-react": "^7.7.0",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "file-loader": "^1.1.11",
    "happypack": "^5.0.0-beta.3",
    "html-webpack-plugin": "^3.2.0",
    "postcss-cssnext": "^3.1.0",
    "postcss-loader": "^2.1.3",
    "react": "^16.3.1",
    "react-dom": "^16.3.1",
    "style-loader": "^0.20.3",
    "url-loader": "^1.0.1",
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14",
    "webpack-dev-server": "^3.1.3"
  },
  "dependencies": {
    "jquery": "^3.3.1"
  }
}

webpack._dllconfig.js

const path = require('path');
//DllPlugin 用于打包出一个个单独的动态链接库文件
const DllPlugin = require('webpack/lib/DllPlugin');
module.exports = {
    entry:{
        react:['react','react-dom']
    },
    output:{
        filename:'[name].dll.js',
        path:path.resolve(__dirname,'dist'),
        library:'_dll_[name]',
    },
    plugins:[
        new DllPlugin({
            name:'_dll_[name]',
            path:path.join(__dirname,'dist','[name].mainfest.json')
        })
    ]
}

.babelrc

{
    "presets": [
        "es2015",
        "react"
    ]
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏漫漫前端路

前端安全知识

xss: 跨站脚本攻击(Cross Site Scripting)是最常见和基本的攻击 WEB 网站方法,攻击者通过注入非法的 html 标签或者 javasc...

12320
来自专栏北京马哥教育

DNS从入门到管理(一)

DNS概述 DNS(Domain Name System,域名系统),域名和IP地址相互映射的一个分布式数据库,通过主机名,最终得到该主机名对应的IP地址的过程...

69160
来自专栏IT笔记

本地私服仓库nexus3.3.1使用手册

私服架构 私服是指私有服务器,是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构建。有了私服之后,当 Maven 需要下载构件时,直接请求私服...

1.5K80
来自专栏linux运维学习

linux学习第二十八篇:监控io性能,free命令,ps命令,查看网络状态,linux下抓包

监控磁盘io性能 (命令:iostat,iotop) 查看磁盘读写状态: iostat -x %util:表示io等待,也就是磁盘使用占用cpu百分比。...

81490
来自专栏白驹过隙

Socket编程回顾,一个最简单服务器程序

23530
来自专栏散尽浮华

Linux系统下的ssh使用(依据个人经验总结)

对于linux运维工作者而言,使用ssh远程远程服务器是再熟悉不过的了!对于ssh的一些严格设置也关系到服务器的安全维护,今天在此,就本人工作中使用ssh的经验...

83170
来自专栏逸鹏说道

Ubuntu抛弃了Untiy转向Gnome,美化之路怎么办?不用怕咱一步一步大变身!

跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 常用软件安装+系统软件卸载:http:...

36770
来自专栏Fred Liang

小米路由器 3G mentohust 以及 SS 配置

正常情况下校园网的网速是 10mb/s,尤其是在使用华科的镜像源的时候,速度可以稳定在11+mb/s。 由于之前百兆路由器速度限制,只能达到2mb/s,因此更...

61630
来自专栏linux系统运维

原 添加自定义监控项目,配置邮件告警,测

21530
来自专栏皮振伟的专栏

[linux][memory]进程的最大内存使用量的讨论

前言: 一个进程最大能使用多少虚拟内存,能控制的地方还是比想象的多一点。 尤其是IaaS上,一个qemu进程能使用多少虚拟内存,就是对应着虚拟机的物理内存的最大...

2.6K110

扫码关注云+社区

领取腾讯云代金券