webpack2.0搭建前端项目的教程详解


Posted in Javascript onApril 05, 2017

一、什么是webpack:

webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

注意: 目前最新为webpack2.0版本,与1.0有一些出入

二、初始化项目

npm init

npm install webpack --save-dev

三、安装loader,stylus以及postCss

npm install style-loader css-loader stylus-loader stylus --save-dev
npm install --save-dev postcss-loader autoprefixer

四、目录结构大致如下

webpack2.0搭建前端项目的教程详解

五、添加webpack.config.js 配置如下:

// 该配置基于webpack2.0 详情查看 https://webpack.js.org/guides/migrating/
const path = require('path'); // 导入路径包

module.exports = {
 entry: './src/main.js', //入口文件
 output: {
 path: path.resolve(__dirname, 'build'), // 指定打包之后的文件夹

 // publicPath: '/assets/', // 指定资源文件引用的目录,也就是说用/assests/这个路径指代path,开启这个配置的话,index.html中应该要引用的路径全部改为'/assets/...'
 // filename: 'bundle.js' // 指定打包为一个文件 bundle.js
 filename: '[name].js' // 可以打包为多个文件
 },
 // 使用loader模块
 module: {
 /* 在webpack2.0版本已经将 module.loaders 改为 module.rules 为了兼容性考虑以前的声明方法任然可用,



同时链式loader(用!连接)只适用于module.loader,



同时-loader不可省略 */
 rules: [{
  test: /\.css$/,
  use: [
  'style-loader', {
   loader: 'css-loader',
   options: {
   // modules: true // 设置css模块化,详情参考https://github.com/css-modules/css-modules
   }
  }, {
   loader: 'postcss-loader',
   // 在这里进行配置,也可以在postcss.config.js中进行配置,详情参考https://github.com/postcss/postcss-loader
   options: {
   plugins: function() {
    return [
    require('autoprefixer')
    ];
   }
   }
  }
  ]
 }, {
  test: /\.styl(us)?$/,
  use: [
  'style-loader', 'css-loader', {
   loader: "postcss-loader",
   options: {
   plugins: function() {
    return [
    require('autoprefixer')
    ];
   }
   }
  }, 'stylus-loader'
  ]
 }]
 }
}

在index.html中引入'/build/main.js'。main.js 代码如下

require('./common/css/style.css'); require('./common/css/stylus.styl');

六、通过webpack-dev-server实现页面的自动刷新。

首先安装webpack-dev-server

npm install --save-dev webpack-dev-server

然后修改package.json配置文件中:

"scripts": {
 "start": "webpack-dev-server",
 "build": "webpack"
 }

使用npm start 启动服务。npm的 start是一个特殊的脚本名称,它的特殊性表现在,在命令行中使用npm start就可以执行相关命令,如果对应的此脚本名称不是start,想要在命令行中运行时,需要这样用npm run {script name} ,所以打包命令修改为npm run build

这里如果使用webpack-dev-server 命令来启动就必须全局安装 devServer:

npm install webpack-dev-server -g

在webpack的配置文件中可以对devServer进行配置

// 配置devServer各种参数
 devServer: {
 contentBase: "./", // 本地服务器所加载的页面所在的目录
 historyApiFallback: true, // 不跳转
 inline: true // 实时刷新
 }

此时可以监听入口文件的改变,实时刷新页面,然而非入口文件的改变则不会被监听到,需要手动进行刷新。并且目标文件不包括index.html。这里使用html-webpack-plugin插件。

npm install html-webpack-plugin --save-dev

修改webpack配置文件,添加以下配置:

...
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
 ....,
 plugins: [
 new HtmlWebpackPlugin({
  template: './index.html' // 模版文件
 })
 ]
}

这里记录一下遇到的坑:首先,devServer其实读取的是打包之后的文件,但是这些文件是存储在内存当中(并不会显示在build下)。然后由于使用HtmlWebpackPlugin这个插件,它可以自动帮你将打包的js插入模版html文件中,因此我们要将原文件(就是作为模版的index.html文件)中插入的main.js这行代码去掉。然后如果开启了publicPath这个选项,HtmlWebpackPlugin会插入publicPth选项的路径('/assets/main.js'),devServer的index.html此时是无法读取到该目录下的文件。但是奇怪的是devServer此时直接没有插入该scripts。。不知道为啥。。但是为了部署的问题,cdn啥的,对开发环境和生产环境应该开启不同的publicPath,也就是说开发和生产应该使用两个不同的配置文件(包括sourcemap,devserver都不应该出现在生产的配置中)。

七、sourcemap 让开发更易于调试

module.exports = {
 devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项
 ....
 }
}

webpack2.0搭建前端项目的教程详解

八、使用ES6语法

webpack2.0增加了对ES6模块的支持,无需额外的配置,并且可以与 AMD 和 CommonJS混用。webpack 2可以分析理解所有的ES6代码并且只在检测到是ES6模块时才使用tree-shaking。然而,只有import导入和export导出的模块才会被编译为ES5,如果希望所有的打包文件都编译为ES5,你需要使用一个转译器来处理剩下来的文件。这里我使用babel。首先安装babel:

npm install --save-dev babel-core babel-loader babel-preset-es2015

在根目录下添加.babelrc文件,并添加配置

如果bable的配置仍然为:

{
 presets: ['es2015']
}

那么无用的代码也会被打包(Babel会将ES 6模块通过commonJs模块转换输出,然后webpack 2就不能进行tree-shaking分析了)。这块儿大致原理是这样的。。。

因此我们将配置文件改为:

{
 "presets": [
  ["es2015", {"modules": false}]
 ]
}

并且在webpack的配置文件中加入如下loader(此处一定不能用use,不知道为啥)

{
 test: /\.js$/,
 loader: 'babel-loader', //此处不能用use,不知道为啥
 exclude: /node_modules/ //需要排除的目录
}

九、热加载模块(HMR)

webpack配置文件中,devServer的“inline”选项会为入口页面添加“热加载”功能,“hot”选项则开启“热替换(Hot Module Reloading)”,即尝试重新加载组件改变的部分(而不是重新加载整个页面)。如果两个参数都传入,当资源改变时,webpack-dev-server将会先尝试HRM(即热替换),如果失败则重新加载整个入口页面。要使用HRM,首先需要在webpack配置文件中配置plugin:

plugins: [
  ...
  new webpack.HotModuleReplacementPlugin() // 热加载插件
 ]

到这一步,实际上改变css可以实现hrm,然而js只会刷新整个页面,index.html直接不刷新了。。。不知道为啥。react可以通过react-transform-hrm来搞定。非react框架现在考虑用webpack-dev-middleware 来尝试一下

十、生产环境

 通过以上步骤基本的开发环境就搭建完毕了,那么实际上在生产环境里可能会有其他的要求,例如分离js与css(目前css是打包到js中去的),例如压缩代码等。

首先创建一个webpack.production.config.js,然后在package.json中配置修改为:

"scripts": {
 "start": "webpack-dev-server",
 "build": "set NODE_ENV=production&&webpack --config ./webpack.production.config.js"
 }

当运行 npm run build 的时候,会设置环境变量"NODE_ENV"为"production"。

var prod = process.env.NODE_ENV === 'production' ? true : false;

现在分别介绍几个常用的插件:

      1.提取公共模块插件(webpack内置) CommonsChunkPlugin

      2.压缩js插件(webpack内置) UglifyJsPlugin

      3.分离css文件: ExtractTextPlugin 注意该插件由于和webpack2不兼容,需要指定版本。。在webpack.production.config.js 中的配置,注意与1.x版本loader的写法不同。

      4.清除文件夹: clean-webpack-plugin

运用[hash]使得产生的文件名带有哈希值,合理使用缓存。

项目地址: https://github.com/Dyzzi/webpack-demo-project

本地下载:点击这里

总结

以上就是这篇文章的全部内容了,至此大致的开发以及生产环境已经搭建完毕。希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持

Javascript 相关文章推荐
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
Oct 23 Javascript
js调用css属性写法
Sep 21 Javascript
jquery实现邮箱自动补全功能示例分享
Feb 17 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
Nov 15 Javascript
详解Angularjs中的依赖注入
Mar 11 Javascript
JavaScript基于对象去除数组重复项的方法
Oct 09 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
Jan 13 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
Jan 19 Javascript
浅谈JS对html标签的属性的干预以及对CSS样式表属性的干预
Jun 25 Javascript
node.js实现的装饰者模式示例
Sep 06 Javascript
利用Console来Debug的10个高级技巧汇总
Mar 26 Javascript
Vue2.0实现组件之间数据交互和通信操作示例
May 16 Javascript
详解使用fetch发送post请求时的参数处理
Apr 05 #Javascript
详解用webpack2.0构建vue2.0超详细精简版
Apr 05 #Javascript
关于vuex的学习实践笔记
Apr 05 #Javascript
详解基于webpack和vue.js搭建开发环境
Apr 05 #Javascript
ionic2打包android时gradle无法下载的解决方法
Apr 05 #Javascript
使用gulp搭建本地服务器并实现模拟ajax
Apr 05 #Javascript
Vue.js render方法使用详解
Apr 05 #Javascript
You might like
在任意字符集下正常显示网页的方法一
2007/04/01 PHP
table标签的结构与合并单元格的实现方法
2013/07/24 PHP
php获取URL中带#号等特殊符号参数的解决方法
2014/09/02 PHP
PHP批量去除BOM头内容信息代码
2016/03/11 PHP
thinkphp5框架扩展redis类方法示例
2019/05/06 PHP
laravel实现上传图片的两种方式小结
2019/10/12 PHP
JavaScript For Beginners(转载)
2007/01/05 Javascript
javascript的trim,ltrim,rtrim自定义函数
2008/09/21 Javascript
javascript中的new使用
2010/03/20 Javascript
eval与window.eval的差别分析
2011/03/17 Javascript
JQuery页面图片切换和新闻列表滚动效果的具体实现
2013/09/26 Javascript
javascript向后台传送相同属性的参数即数组参数
2014/02/17 Javascript
jquery实现效果比较好的table选中行颜色
2014/03/25 Javascript
轻松学习jQuery插件EasyUI EasyUI创建菜单与按钮
2015/11/30 Javascript
JavaScript数据结构之二叉树的删除算法示例
2017/04/13 Javascript
分享5个顶级的JavaScript Ajax组件库
2018/09/16 Javascript
Vue框架下引入ActiveX控件的问题解决
2019/03/25 Javascript
JS实现利用闭包判断Dom元素和滚动条的方向示例
2019/08/26 Javascript
python实现批量获取指定文件夹下的所有文件的厂商信息
2014/09/28 Python
Python3实现的字典、列表和json对象互转功能示例
2018/05/22 Python
用python生成1000个txt文件的方法
2018/10/25 Python
Django csrf 两种方法设置form的实例
2019/02/03 Python
python自带tkinter库实现棋盘覆盖图形界面
2019/07/17 Python
详谈tensorflow gfile文件的用法
2020/02/05 Python
python爬虫基础知识点整理
2020/06/02 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
2020/06/05 Python
python连接手机自动搜集蚂蚁森林能量的实现代码
2021/02/24 Python
html5组织文档结构_动力节点Java学院整理
2017/07/11 HTML / CSS
喜诗官方在线巧克力店:See’s Candies
2017/01/01 全球购物
PHP如何对用户密码进行加密
2014/07/31 面试题
旅游项目开发策划书
2014/01/18 职场文书
护理助产毕业生的求职信
2014/03/02 职场文书
机关党员2014全国两会学习心得体会
2014/03/10 职场文书
机电一体化毕业生自荐信
2014/06/19 职场文书
学校重阳节活动总结
2015/03/24 职场文书
2015年物流客服工作总结
2015/07/27 职场文书