Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端工程化 #2

Open
UNDERCOVERj opened this issue Mar 24, 2018 · 0 comments
Open

前端工程化 #2

UNDERCOVERj opened this issue Mar 24, 2018 · 0 comments

Comments

@UNDERCOVERj
Copy link
Owner

概念:

  • webpack 是一个现代 JavaScript 应用程序的静态模块打包器
  • 将所有这些模块打包成一个或多个 bundle。

背景:

  • 开发工作的复杂度日趋增加
  • 对自动化构建的要求变高
  • 提升开发效率:
    • 模块管理
    • 引用分析
    • 资源打包处理
    • 自动输出
    • 压缩合并

自动化构建流程:

  1. 读取入口文件
  2. 分析模块引用
  3. 按照引用模块加载
  4. 模块文件编译处理
  5. 文件资源合并
  6. 文件优化处理
  7. 写入生成目录
  8. 持续集成

自动化工具设计

  1. 模块引入分析(ast)
  2. 模块化规范支持
  3. css编译,自动合并图片
  4. html,js,css资源合并与优化
  5. 资源路径替换
  6. 开发和生产环境切换
  7. 异步文件打包方案
  8. 构建发布

webpack优势:

  1. 资源管理强大,支持amd,cmd,commonjs等多种标准
  2. 串联式模块加载器以及插件机制,预编译(sass,less,图片转base64等),串联指less-loader将less转为css,然后通过css-loader转为css模块
  3. 切割模块,实现公共模块或按需加载
  4. 支持es6,ts等语法
  5. 支持热更新
  6. 支持静态文件名hash化
  7. 任何资源都能被import
  8. 支持静态文件自动合并
  9. 环境变量,区分开发环境和生产环境
  10. devtool,便于编译后的调试
  11. 自定义程度高,可自己编写loader和plugin

缺点:

  1. 打包太慢
  2. 配置繁琐
  3. API太多
  4. 体积太大
  5. 难调试
  6. 日志多

webpack核心概念

  1. entry: 告诉webpack从哪里开始并通过依赖关系图得知哪些文件要打包
  2. output:制定构建好的资源文件如何写入到制定目录,只能有一个出口
  3. loader:加载器,用于将所有类型资源代码转换成webpack能理解的模块,允许在导入或者加载它们时预处理文件。可以import所有文件
  4. plugins:插件,服务于编译期间,是一个具有apply属性的js对象,其apply会被webpack。 compiler调用,并且compiler对象可在整个编译生命周期访问。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量
  5. chunk:被entry所依赖的额外代码块,可以包含一个或者多个文件,所有的资源都以模块的形式存在
  6. modules:webpack中放置loaders的地方,可集中在rules数组中进行管理
  7. resolve:设置对资源的寻址和解析规则,可通过alias和extensions来进行解析规则定制
  8. externals:从输出的bundle中排除依赖,多在library开发或者加载中使用
  9. manifest:文件清单,当compiler开始执行、解析、映射应用程序时,它会保留所有模块的详细要点,使用manifest中的数据,runtime将能够查询模块标识符,检索出背后对应的模块

A&Q

  1. hash和chunkhash的区别
  • [hash] is replaced by the hash of the compilation.
output: {
    filename: '[name].[hash:8].js',
    path: __dirname + '/built'
}

hash是compilation对象计算所得,而不是具体的项目文件计算所得。所以以上配置的编译输出文件,所有的文件名都会使用相同的hash指纹

hash可以作为版本控制的一环,将其作为编译输出文件夹的名称统一管理

  • [chunkhash] is replaced by the hash of the chunk.
output: {
    filename: '[name].[chunkhash:8].js',
    path: __dirname + '/built'
}

chunkhash是根据具体模块文件的内容计算所得的hash值,所以某个文件的改动只会影响它本身的hash指纹,不会影响其他文件。

  1. js与css共用相同chunkhash的解决方案:

extract-text-webpack-plugin提供了另外一种hash值:contenthash。顾名思义,contenthash代表的是文本文件内容的hash值,也就是只有style文件的hash值

优化

思路:

  1. 拆包,限制构建范围,不想关的资源不参与构建,减少资源搜索时间
  2. 使用增量构建而不是全局构建
  3. 从webpack存在的不足出发,优化不足,提升效率

打包优化:

  1. 减小打包体积

    1. import css文件的时候,会直接作为模块一并打包到js文件中

    extract-text-webpack-plugin

    • 缺点:
      1. 编译时间变长
      2. 增加http请求
    1. 所有js模块 + 依赖都会打包到一个文件

    使用CommonsChunkPlugin将公用vendor提取出来

    1. React、ReactDOM文件过大

    解决:将react,reactdom缓存起来

    new webpack.optimize.CommonsChunkPlugin({ 
        name: 'vendor',
    	minChunks: function (module) {
    		// any required modules inside node_modules are extracted to vendor
    		return (
    			module.resource &&
    				/\.js$/.test(module.resource) &&
    					module.resource.indexOf(
    						path.join(__dirname, '../node_modules')
    					) === 0
    		)
    	}             
    }),
    new webpack.optimize.CommonsChunkPlugin({
        name: 'manifest'
    }),
    
  2. 代码压缩

webpack-parallel-uglify-plugin插件可以并行运行UglifyJS插件,这可以有效减少构建时间

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
new ParallelUglifyPlugin({
	cacheDir: '.cache/',
	uglifyJS:{
		output: {
			comments: false
		},
		compress: {
			warnings: false
		}
	}
})
  1. 缓存与增量构建
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant