webpack 从入门到放弃



问题: 1. 全局变量泛滥,2. 命名冲突, 3. 依赖关系管理,先去加载 a ,在去加载b, 否则就会报错;

二,模块化的初级阶段:立即执行函数

  1. var moduleA = function(){
  2. var a, b;
  3. return {
  4. message: function(c){
  5. alert(a+b+c)
  6. }
  7. }
  8. }()
  9. (function(window){
  10. // do something
  11. window.jQuery = window.$ = jQuery;
  12. })(window)

优点:模块内可以定义一些私有变量,缺点:仍然会污染全局变量,window.jquery ,没有解决模块依赖;


现代模块时代:

1. commonjs   , node 提出,同步不太适合浏览器,

  1.   var math = require(‘math‘);
  2. math.add(2, 3);

在服务器端,文件都是在硬盘中,而在浏览器中,文件需要网络穿过来,如果一个模块没传过来,整个应用都要停在那里等,浏览器假死;

2. requireJSAMD) , SeaJS ( CMD ),

  1. require([‘math‘], function(math){
  2. math.add(2,3)
  3. })

异步,传入回调函数作为参数,等加载完成后执行;

3. ES6 Module, 目前比较流行;

  1. import math from ‘math‘;
  2. math.add(2, 3);

模块化的目的:高内聚,低耦合;

前端的模块加载:

前端模块要在 浏览器中运行,必经的过程就是从服务器到浏览器的传输;两个极端方式:1. 每一个模块都发起一个请求; 2. 所有模块打包成一个,只请求一次;

显然,都不好;按需加载是比较合适的;

前端的模块不仅仅有js,还有css,less, sass,图片,他们都是模块,都可以用require的方式加载;

  1. require(‘./style.css‘);
  2. require(‘./style.less‘);
  3. require(‘./style.jade‘);
  4. require(‘./image.png‘);

webpack 本身只能处理js ,如果想处理其他类型的文件,就需要用到 loader 进行转换;loader 本身是一个函数,接受源文件作为参数,返回转换后的结果;

loader的特点:

  1. 可以链式调用,我处理完了交给你接着处理,但是最后一个loader必须返回javascript
  2. loader 可以同步或者异步执行
  3. loader 可以运行在 nodejs中,所以可能做任何事情
  4. loader 通过参数来传递配置
  5. 插件让loader 有更多的特性
  1. var webpack = require(‘webpack‘);
  2. module.exports = {
  3. entry: ‘./entry.js‘,
  4. output: {
  5. path: __dirname,
  6. filename: ‘bundle.js‘
  7. },
  8. module:{
  9. loaders: [
  10. {test: /\.css$/, loader: ‘style-loader!css-loader‘}
  11. ]
  12. }
  13. }

添加插件,可以让loader 更加强大。插件有内置的,也有第三方的;

  1. var webpack = require(‘webpack‘);
  2. module.exports = {
  3. entry: ‘./entry.js‘,
  4. output: {
  5. filename: ‘bundle.js‘
  6. },
  7. module: {
  8. loaders: [
  9. { test:/\.css$/, loader: ‘style-loader!css-loader‘}
  10. ]
  11. },
  12. plugin: [
  13. new webpack.BannerPlugin(‘dujuncheng created‘)
  14. ]
  15. }

1. 安装

/ dudu01  执行 npm init ,

  1. npm init

会把该文件夹变成一个项目,会自动生成一个package.json 配置文件;

  1. cnpm install webpack --save

为了把webpack 添加到项目依赖里面;

package.json 文件里面会多了一个字段:

  1. "dependencies": {
  2. "webpack": "^2.5.1"
  3. }

2. webpack 会自动将文件进行打包

安装好了以后,我们新建两个文件:index.html, entry.js

  1. // index.html
  2. <div id=‘app‘></div>
  3. <script src = ‘bundle.js‘>
  4. //entry.js
  5. document.getElementById(‘app‘).textContent = ‘hello‘

然后我们在控制台输入:

  1. webpack entry.js bundle.js

3. webpack 会自动分析 依赖,

webpack 会自动分析 entry.js里面依赖了哪些文件,会自动一起打包到bundle.js 里面;

我们新建一个bundle.js 文件,里面写的是:

  1. module.exports = ‘dujuncheng‘

在entry.js 里面引入:

  1. var name = require(‘./name‘);
  2. document.getElementById(‘app‘).textContent=‘hello‘+name

通过

  1. webpack entry.js bundle.js

再次打包,我们就可以把entry.js依赖的name.js 一起打包进入bundle.js

4. loader

webpack 本身只能处理js ,如果想处理其他类型的文件,就需要用到 loader 进行转换;loader 本身是一个函数,接受源文件作为参数,返回转换后的结果;

如果我们想使用一个loader ,那么我们必须要手动安装;

  1. cnpm install css-loader style-loader --save

在package.json里面就会多了loader:

  1. "dependencies": {
  2. "css-loader": "^0.28.1",
  3. "style-loader": "^0.17.0",
  4. "webpack": "^2.5.1"
  5. }

我们新建webpack.config.js, 里面的内容是:

  1. module.exports = {
  2. entry: ‘./entry.js‘,
  3. output: {
  4. path: __dirname,
  5. filename: ‘bundle.js‘
  6. },
  7. module: {
  8. loaders:[
  9. { test:/\.css$/, loader: ‘style-loader!css-loader‘ }
  10. ]
  11. }
  12. }

多了一个module 对象,里面有一个数组 loaders, 数组的每一项都是对象,{test: /\.css$/, loader: ‘style-loader! css-loader‘}

这就是告诉 webpack, 只要是css , 就需要用这两个loader 进行处理;

我们新建一个style.css,一会要把它打包进 bundle.js

  1. body {
  2. background-color: red
  3. }
  1. //entry.js
  2. require(‘./style.css‘);
  3. document.getElementById(‘app‘).textContent = ‘dujuncheng‘ ;

我们把css  文件引入了js ,中间会自动用 css-loader , style-loader 进行处理;

  1. // 因为我们配置了webpack.config.js 配置文件,所以我们只要 webpack 就可以打包了
  2. webpack

5. source map



 在没有用sourcemap的时候,我们在开发人员工具那里,看到了有 index.html 和 bundle.js

bundle. js 不用我们关心,因为是打包后的,我们需要关心的是 source-map

  1. webpack --devtool source-map



 项目中会多了一个 bundle.js.map 的文件,我们的浏览器窗口下:


 source-map 方便了我们的调试,在name.js 文件里面,添加: debugger ,我们就可以在那个位置打一个断点;

如果我们不想在每一次的webpack 都带一个 devtool  我们可以在webpack.config.js 文件里面进行修改:

  1. module.exports = {
  2. entry: ‘./entry.js‘,
  3. output: {
  4. path: __dirname,
  5. filename: ‘bundle.js‘
  6. },
  7. devtool: ‘source-map‘,
  8. module: {
  9. loaders: [
  10. {
  11. test: /\.css$/,
  12. loader: ‘style-loader!css-loader‘
  13. }
  14. ]
  15. }
  16. }

webpack 和 babel  进行配合

  1. cnpm install babel-loader babel-core babel-preset-es2015 --save-dev

code splitting

两个极端的的情况,我们把所有的文件都打包到一个文件里面,或者我们的每个文件都要分别打包;这两个都不好;

怎么做?

1. 分离业务代码和第三方库  [ vender ]

2. 分离css 文件

3. 按需加载  [ import() ]

第三方库更新较慢,并且可以锁版本,利用浏览器的缓存来加载第三方的库;

按需加载,用户访问了某一个路由的时候,再去加载相应的组件;

首先,我们想可视化的看到,我们的文件中是哪些比较占体积:webpack-bundle-analyzer

  1. npm install --save-dev webpack-bundle-analyzer
  2. //webpack.config.js
  3. var BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer‘).BundleAnalyzerPlugin;
  4. // ...
  5. plugins: [new BundleAnalyzerPlugin()]
  6. // ...

通过这个插件,我们就可以很直观的分析啦;

分离第三方的库:我们的思路是:把node_module 里面的用到的 js插件,都放到vender.js 里面

用webpack 自带的 commonChunkPlugin:

  1. new webpack.optimize.CommonsChunkPlugin({
  2. name: ‘vendor‘,
  3. minChunks: ({ resource }) => (
  4. resource && resource.indexOf(‘node_modules‘) >= 0 && resource.match(/\.js$/))
  5. }),

按需加载

很简单,需要改两个地方:路由声明组件的那个地方,output的文件名;

1. 路由声明组件:

  1. // import test1 from ‘@/components/test1‘
  2. // import test2 from ‘@/components/test2‘
  3. // import test3 from ‘@/components/test3‘
  4. const test1 = () => import(
  5. /* webpackChunkName: "Emoji" */
  6. ‘@/components/test1‘)
  7. const test2 = () => import(
  8. /* webpackChunkName: "Emoji" */
  9. ‘@/components/test2‘)
  10. const test3 = () => import(
  11. /* webpackChunkName: "Emoji" */
  12. ‘@/components/test3‘)

2. chunkFilename修改

  1. filename: ‘[name].js‘,
  2. chunkFilename: ‘[name].chunk.js‘,

如果你用了 Babel ,就需要装上这个插件:babel plugin syntax dynamic import 来解析 import() 语法。修改 .babelrc :

  1. {
  2. "plugins": ["syntax-dynamic-import"]
  3. }

null

时间: 2024-10-10 17:09:31

webpack 从入门到放弃的相关文章

webpack -&gt; vue Component 从入门到放弃(二)

Foreword 上一篇简单介绍了webpack的打包功能,应该说是比较无意义的打包,对于开发人员来说,这种效率是非常低的.所以我们来点升华. First Step 我们给第一篇例子中加个样式文件我们 style.css body { background: yellow; } 然后修改 entry.js require("!style-loader!css-loader!./style.css") // 载入 style.css document.getElementById('ap

从入门到放弃,.net构建博客系统(二):依赖注入

文章目录:<从入门到放弃,.net构建博客系统> 从入门到放弃,.net构建博客系统(一):系统构建 从入门到放弃,.net构建博客系统(二):依赖注入 上一篇中有讲到项目启动时会进行ioc的依赖注入,但具体是怎么注入的呢?我们先一步步往下走 一.注册autofac配置 首先bootstraper会进行初始化,接着将当前mvc控制器工厂改为AutofacControllerFactory. 1 public class AutofacConfig 2 { 3 /// <summary&g

《Java从入门到放弃》文章目录

转眼半个月过去了,不知不觉也写了10篇博客,突然发现所有的目录都没有纯列表的展示,所以特意写一个目录篇,来记录该系列下所有的文章. 当然,因为现在还没有写完,所以先按时间顺序排列,等相关内容都写完后,再按学习顺序来整理. <Java从入门到放弃>入门篇:XMLHttpRequest的基本用法 <Java从入门到放弃>入门篇:Struts2的基本访问方 <Java从入门到放弃>入门篇:Struts2的基本访问方式(二) <Java从入门到放弃>入门篇:Stru

iOS 即时通讯,从入门到 “放弃”?

原文链接:http://www.jianshu.com/p/2dbb360886a8 本文会用实例的方式,将 iOS 各种 IM 的方案都简单的实现一遍.并且提供一些选型.实现细节以及优化的建议. —— 由宇朋Look分享 前言 本文会用实例的方式,将iOS各种IM的方案都简单的实现一遍.并且提供一些选型.实现细节以及优化的建议. 注:文中的所有的代码示例,在github中都有demo:iOS即时通讯,从入门到“放弃”?(demo)可以打开项目先预览效果,对照着进行阅读. 言归正传,首先我们来总

NDK开发 从入门到放弃(七:Android Studio 2.2 CMAKE 高效NDK开发)

前言 之前,每次需要边写C++代码的时候,我的内心都是拒绝的. 1. 它没有代码提示!!!这意味着我们必须自己手动敲出所有的代码,对于一个新手来说,要一个字母都不错且大小写也要正确,甚至要记得住所有的jni函数等,真是太折磨人了-平时写java代码的时候都是写几个字母会出来一大堆提示然后选择的,这样还有一个好处就是很多时候我们不知道有那些函数,但是我们可以通过obj.,然后就可以看到它有哪些方法函数了. 2. 很多地方会显示为红色,就像是错误提示的那种,当然,如果没错的话还是能编译运行的,但是如

CYQ.Data 从入门到放弃ORM系列:开篇:自动化框架编程思维

前言: 随着CYQ.Data 开始回归免费使用之后,发现用户的情绪越来越激动,为了保持这持续的激动性,让我有了开源的念头. 同时,由于框架经过这5-6年来的不断演进,以前发的早期教程已经太落后了,包括使用方式,及相关介绍,都容易引人误解. 为此,我打算重新写个系列来介绍最新的版本,让大伙从传统的ORM编程过渡到自动化框架型思维编程(自已造的词). 于是:这个新系列的名称就叫:CYQ.Data 从入门到放弃ORM系列 什么是:CYQ.Data 1:它是一个ORM框架. 2:它是一个数据层组件. 3

webpack入坑之旅(三)webpack.config入门

这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不是开始的开始 webpack入坑之旅(二)loader入门 webpack入坑之旅(三)webpack.config入门 webpack入坑之旅(四)扬帆起航 webpack入坑之旅(五)加载vue单文件组件 webpack入坑之旅(六)配合vue-router实现SPA 在上面我们已经尝试过了两种

shell从入门到放弃 第二步 ++

此文承接 shell从入门到放弃 第一步 由此,继续从小白到放弃的第二部分@[email protected] 一.shell的运算符 Shell支持很多运算符,包括:Shell算数运算符.关系运算符.布尔运算符.字符串运算符等 算术运算    算术运算符:        +,-        *, /        %:取余        **:次方            算术运算格式:        (1) let  VAR=算术表达式         (2) VAR=$[算术表达式]  

Python的函数式编程,从入门到?放弃?

转:http://python.jobbole.com/84927/ 很早以前就听说过了函数式编程,印象中是一种很晦涩难懂的编程模式,但却一直没有去进行了解. 恰好这周组内的周会轮到我主持,一时也没想到要分享什么.灵光一闪,就选定函数式编程这个主题吧,反正组里的同事都没有学过,只需要讲解入门方面的知识就好,也正好可以借这个机会逼迫自己去学习下这种新的编程方式. 经过初步了解,发现支持函数式编程的语言挺多的,除了像Lisp.Scheme.Haskell.Erlang这样专用的函数式编程语言,我们常