专栏名称: freeCodeCamp
FreeCodeCamp.cn官方公众号
目录
相关文章推荐
中国交建  ·  听!这是来自中交建设者的“黄河大合唱” ·  4 天前  
中国城市规划  ·  会议 | 传承历史文化 ... ·  6 天前  
中国铁建  ·  善作善为,建立真正的市场化经营机制 ·  6 天前  
51好读  ›  专栏  ›  freeCodeCamp

webpack2 的入门手册

freeCodeCamp  · 公众号  ·  · 2017-08-02 18:29

正文


背景


一直对webpack的打包流程很感兴趣,但是无奈官网文档实在太多,搜出来的大部分文章要么偏理论要么纯粹讲过程不讲原理,最近终于找到一篇入门文章,文章对于初学者讲的很清晰,但是由于是英文的,而且我没有找到这篇文章对应的中文翻译版,所以本文主要是对那篇文章进行翻译,介绍一下webpack2的入门知识。


webpack2入门手册(译文)


Webpack是一个模块打包机


Webpack已然成为当前web开发最重要的工具之一。首先它是一个Javascript的打包工具,但同时他也能打包包括HTML,CSS,甚至是图片等形式的资源。它能更好的控制你正在编写的App的HTTP请求,并且允许你去使用更多的资源(如Jade,Sass以及ES6)。Webpack同时允许你更容易的从npm获取安装包。


这篇文章主要面向那些对于webpack完全陌生的同学,内容将包括初始安装和配置,模块,模块加载器,插件,代码拆分以及模块热替换(HMR,hot module replacement)。如果你觉得入门视频比较有用的话,我推荐Glen Maddern的Webpack初体验作为开始学习的起点,会让你理解为什么webpack如此特殊。


为了更加后续的阅读,请确保先安装了Node.js,安装可以参考Node.js安装教程。你也在Github上下载到对应的Demo。


安装


让我们用npm和webpack新建一个项目吧:


mkdir webpack-demo

cd webpack-demo

npm init -y

npm install webpack@beta --save-dev

mkdir src

touch index.html src/app.js webpack.config.js


编辑以下文件:


 

   

    Hello webpack

 

 

   

   

   

   

 



 

   

    Hello webpack

 

 

   

   

   

 


试试在浏览器中重新加载index.html和admin.html,看看自动生成的公共模块部分。


抽取CSS


另一个受欢迎的插件是extract-text-webpack-plugin,它的用途是抽取模块到对应的结果文件中。


下面我们在配置文件中修改.scss的规则编译成对应的Sass文件,加载CSS,接着把他们抽取到各自的CSS包中,这样就可以把它们从Javascript包中移除。


npm install [email protected] --save-dev



// webpack.config.js

const ExtractTextPlugin = require('extract-text-webpack-plugin')

const extractCSS = new ExtractTextPlugin('[name].bundle.css')


const config = {

  // ...

  module: {

    rules: [{

      test: /\.scss$/,

      loader: extractCSS.extract(['css-loader','sass-loader'])

    }, {

      // ...

    }]

  },

  plugins: [

    extractCSS,

    // ...

  ]

}


重启webpack你会看到一个新的打包后的文件app.bundle.css,你可以照例直接引用它。


 

   

    Hello webpack

   

 

 

   

   

   

 


刷新页面,确认CSS已经被编译过了,并从app.bundle.js移到了app.bundle.css,成功了!


代码拆分


我们已经看了几种代码拆分的方法:


手动创建单独的入口文件

自动将公共代码拆分到公共模块中

使用extract-text-webpack-plugin从编译后的代码中抽取出来

拆分包还有其他方法:System.import和require.ensure。通过在这些函数中包含代码段,你可以创建一个在运行时按需加载的模块。这个从根本上提高了性能,因为在启动过程中不需要把所有东西都发送到客户端。System.import将模块名作为参数,并返回一个Promise对象。require.ensure获取依赖关系的列表,回调函数以及可选的模块名。


如果应用程序的某一部分具有很大的依赖关系,则应用程序的其余部分就不需要了,最好的方式就是拆分到各个模块中去。我们通过新建一个需要依赖d3的模块dashboard.js来证明这点。


npm install d3 --save



// src/dashboard.js

import * as d3 from 'd3'


console.log('Loaded!', d3)


export const draw = () => {

  console.log('Draw!')

}


在app.js的顶部引入dashboard.js:



// ...


const routes = {

  dashboard: () => {

    System.import('./dashboard').then((dashboard) => {

      dashboard.draw()

    }).catch((err) => {

      console.log("Chunk loading failed")

    })

  }

}

// demo async loading with a timeout

setTimeout(routes.dashboard, 1000)


因为我们加载了异步模块,我们需要在配置文件中增加output.publicPath属性,因此webpack知道去哪里获取。


// webpack.config.js


const config = {

  // ...

  output: {

    path: path.resolve(__dirname, 'dist'),

    publicPath: '/dist/',

    filename: '[name].bundle.js'

  },

  // ...

}


运行npm build操作,你会看到一个新的神秘的打包文件0.bundle.js。



注意webpack为了保持诚实,通过凸现[big]的包来让你保持关注。 这个0.bundle.js将会通过JSONP的请求按需加载,所以从文件目录中获取将不在有效,我们需要启动一个服务来获取文件。


python -m SimpleHTTPServer 8001


打开浏览器,输入http://localhost:8001/ 加载一秒钟后,你会获得一个GET请求,我们动态生成了/dist/0.bundle.js文件,在控制台上打印除了"Loaded!",成功!


webpack开发服务器


当文件改变时,实时地重新加载能提高开发者的开发效率。只要安装它,并且以webpack-dev-server的形式启动,就可以体验啦。


npm install [email protected] --save-dev


修改package.json中的start脚本:


"start": "webpack-dev-server --inline",


重新运行npm start,在浏览器中打开http://localhost:8080


试着去改变src目录中任何文件,如改变people.js中的任意一个名字,或者style.scss中的任意样式,去看看它如何实时改变。


热模块替换(热更新)


如果你对实时重新加载印象深刻,那么hot module replacement(HMR)一定会让你吃惊不已。


现在是2017年了,你在工作中已经可以在单页面应用中使用全局状态了。在开发过程中,你可能会对组件进行许多小的修改,并且希望能在浏览器中看到修改后生成的结果,这样可以实时去更改。但是通过刷新页面或者实时热更新并不能改变全局的状态,你就必须重头开始。但是HMR永远地改变了这一问题。


最后对package.json中的start脚本做修改:


"start": "webpack-dev-server --inline --hot",


在app.js中告诉webpack去接受这个模块以及对应依赖的热更新。


if (module.hot) {

  module.hot.accept()

}

// ...


注意:webpack-dev-server --hot设置了module.hot为true,但只是在开发过程中。当以生产模式打包时,module.hot被设成了false,这样这些包就被从结果中抽离了。


在webpack.config.js中增加一个NamedModulesPlugin插件,去改善控制台的记录功能。


plugins: [

  new webpack.NamedModulesPlugin(),

  // ...

]


最后我们在页面中增加一个元素,我们可以在里面增加一些文字,用来确保我们更改自己模块时页面不会刷新。


 

 

  ...


运行npm start重启服务,观察热更新如何工作吧。


为了实验,在input框中输入“HMR Rules”,接着改变一个people.js中的名字,你会发现页面在不刷新也能做出修改,而忽略input的状态。


这只是一个简单的例子,但是希望你能看到其广泛的用途。在诸如React的开发模式中,你可能有很多"哑巴"组件是与他们的状态分离开的,通过热更新,这些组件将不会失去状态,也能实时更新,因此你将获得及时的反馈。


热更新CSS


修改style.scss文件中

元素的背景颜色,你发现他并没有被HMR替换。


pre {

  background: red;

}


事实证明当你使用style-loader时,CSS的热更新将会免费为你提供而不需要你做任何特殊处理。我们只需要断开CSS模块与最终抽取的包之间的链接,这个包是无法被替换的。


如果我们将Sass规则恢复到原始状态,并从插件列表中删除extractCSS,那么您也可以看到Sass的热重新加载。


{

  test: /\.scss$/,

  loader: ['style-loader', 'css-loader','sass-loader']

}


HTTP/2


使用像webpack这样的模块打包工具的主要好处之一是,您可以通过控制资源的构建方式以及在客户端上的获取方式,从而帮助你提高性能。多年以来,它被认为是最佳实践,通过连接文件减少客户端请求。现在还是有效,但是HTTP2在单一请求中发送多文件,因此连接文件的方式不不再是"银弹"。你的应用程序实际上可以从多个小文件单独缓存,但客户端可以获取单个更改的模块,而不必再次获取大部分相同内容的整个包。


Webpack的创始人Tobias Koppers的撰写了一篇内容丰富的帖子,解释了为什么打包仍然很重要,即使在HTTP/2时代。


想了解更多请参考webpack & HTTP/2


写在结尾的话


我真心希望你已经发现这个介绍webpack 2的文章对你有帮助,并能够开始很好使用它。围绕webpack的配置,加载程序和插件可能需要一些时间,但是了解这个工具的工作原理后会对你有很大帮助。


文档仍在进行更新中,但如果您想将现有的Webpack1项目移到Webpack2,则可以参考Migrating from v1 to v2。


https://webpack.js.org/guides/migrating/


webpack是否是你打包的选择,从评论中你就可以知晓。


本文由Scott Molinari,Joan Yin和Joyce Echessa进行了同行评审。 感谢SitePoint的同行评议人员,使SitePoint内容成为最棒的内容!


注:本人翻译水平有限,如果有错误,欢迎指正。



作者:Mark Brown

译者:Allen Gong

原文链接:https://www.sitepoint.com/beginners-guide-to-webpack-2-and-module-bundling



点击“ 阅读原文 ”,了解更多

推荐文章
中国中铁  ·  中国中铁党委传达学习习近平总书记近期重要讲话重要指示精神
2 天前
中国交建  ·  中交集团主要领导出席公司产业工人队伍培训基地揭牌仪式暨产业工人队伍建设调研座谈会
2 天前
中国交建  ·  听!这是来自中交建设者的“黄河大合唱”
4 天前
中国城市规划  ·  会议 | 传承历史文化 激扬城乡活力——2024历史文化遗产保护青年学术论文丁蜀交流研讨会成功举办
6 天前
中国铁建  ·  善作善为,建立真正的市场化经营机制
6 天前
风青杨  ·  人生有三大悲剧,你集齐了吗?
8 年前
投资数据库  ·  德勤《轨道交通产业投资促进报告》发布公告
7 年前
慈怀读书会  ·  送给妈妈的惊喜 不喜欢算我输!
7 年前
好物控  ·  眼霜这么贵,你抹对了吗?
7 年前
不正常人类研究中心  ·  如果你在微信上聊的很好的朋友突然不理你了,你要好好反思
7 年前