Webpack 是当下最热门的前端资源模块化管理和打包工具。它能够将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还能够将按需加载的模块进行代码分隔,等到实际须要的时候再异步加载。经过 loader 的转换,任何形式的资源均可以视做模块,好比 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。css
首先要安装 Node.js, Node.js 自带了软件包管理器 npm,Webpack 须要 Node.js v0.6 以上支持,建议使用最新版 Node.js。html
一、Webpack可使用npm安装,新建一个空的练习文件夹(此处命名为Webpack),在终端中转到该文件夹后执行下述指令就能够完成安装。前端
// 切换到项目目录 cd /Volumes/MacSysterm/workspace/Web/Webpack //全局安装,之后能够直接在命令端使用webpack命令 npm install -g webpack //安装到你的项目目录,在你的项目下建立一个node_modules文件夹 npm install --save-dev webpack
二、建立package.json文件
在上述练习文件夹中建立一个package.json文件,这是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。在终端中使用npm init命令能够自动建立这个package.json文件。vue
npm init
输入这个命令后,终端会问你一系列诸如项目名称,项目描述,做者等信息,不过不用担忧,若是你不许备在npm中发布你的模块,这些问题的答案都不重要,回车默认便可。node
三、项目中安装Webpack做为依赖包
package.json文件已经就绪,咱们在本项目中安装Webpack做为依赖包jquery
// 安装Webpack npm install --save-dev webpack
四、建立资源文件夹
回到以前的空文件夹,并在里面建立两个文件夹,app文件夹和public文件夹,app文件夹用来存放原始数据和咱们将写的JavaScript模块,public文件夹用来存放准备给浏览器读取的数据(包括使用webpack生成的打包后的js文件以及一个index.html文件)。在这里还须要建立三个文件,index.html 文件放在public文件夹中,两个js文件(Greeter.js和main.js)放在app文件夹中,此时项目结构以下图所示webpack
index.html文件只有最基础的html代码,它惟一的目的就是加载打包后的js文件(bundle.js)laravel
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Webpack Sample Project</title> </head> <body> <div id='root'> </div> <script src="bundle.js"></script> </body> </html>
Greeter.js只包括一个用来返回包含问候信息的html元素的函数。git
//main.js var greeter = require('./Greeter.js'); document.getElementById('root').appendChild(greeter());
main.js用来把Greeter模块返回的节点插入页面。github
// Greeter.js module.exports = function() { var greet = document.createElement('div'); greet.textContent = "Hi there and greetings!"; return greet; };
五、在webpack中引入jquery库
在本地项目目录下通过npm init
初始化生成package.json
文件后,使用下边命令安装jquery包:
➜ npm install jquery --save-dev
安装OK后,咱们就能够在js文件中引入并使用jQuery了
// test.js var $ = require('jquery'); $('div').html('Learning webpack,haha');
module-one.js
文件
document.write('One haha~');
module-two.js
文件
document.write('Two hey~');
./js/entry.js
入口文件
require('./module-one.js'); require('./module-two.js'); document.write('It works.')
经过命令打包生成的bundle.js
文件
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.l = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 2); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { document.write('One haha~'); /***/ }), /* 1 */ /***/ (function(module, exports) { document.write('Two hey~'); /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(0); __webpack_require__(1); document.write('It works.') /***/ }) /******/ ]);
访问index.html
页面
在当前练习文件夹的根目录下新建一个名为webpack.config.js的文件,并在其中进行最最简单的配置,以下所示,它包含入口文件路径和存放打包后文件的地方的路径。
module.exports = { entry: __dirname + "/app/main.js",//已屡次说起的惟一入口文件 output: { path: __dirname + "/public",//打包后的文件存放的地方 filename: "bundle.js"//打包后输出文件的文件名 } }
注:“__dirname”是Node.js中的一个全局变量,它指向当前执行脚本所在的目录。
如今若是你须要打包文件只须要在终端里你运行webpack(非全局安装需使用node_modules/.bin/webpack)命令就能够了,这条命令会自动参考webpack.config.js文件中的配置选项打包你的项目,输出结果以下:
又学会了一种使用Webpack的方法,并且不用管那烦人的命令行参数了,有没有感受很爽。有没有想过若是能够连webpack(非全局安装需使用node_modules/.bin/webpack)这条命令均可以不用,那种感受会不会更爽~,继续看下文。
执行相似于node_modules/.bin/webpack这样的命令实际上是比较烦人且容易出错的,不过值得庆幸的是npm能够引导任务执行,对其进行配置后可使用简单的**npm
start**命令来代替这些繁琐的命令。在package.json中对npm的脚本部分进行相关设置便可,设置方法以下。
"name": "webpack-sample-project", "version": "1.0.0", "description": "Sample webpack project", "scripts": { "start": "webpack" //配置的地方就是这里啦,至关于把npm的start命令指向webpack命令 }, "author": "zhang", "license": "ISC", "devDependencies": { "webpack": "^1.12.9" } }
注:package.json中的脚本部分已经默认在命令前添加了node_modules/.bin路径,因此不管是全局仍是局部安装的Webpack,你都不须要写前面那指明详细的路径了。
npm的start是一个特殊的脚本名称,它的特殊性表如今,在命令行中使用npm
start就能够执行相关命令,若是对应的此脚本名称不是start,想要在命令行中运行时,须要这样用npm
run {script name}如npm run build,如下是执行npm
start后命令行的输出显示
如今只须要使用npm start就能够打包文件了,有没有以为webpack也不过如此嘛,不过不要过小瞧Webpack,其强大的功能包含在其一系列可供配置的选项中,咱们一项项来看。
开发老是离不开调试,若是能够更加方便的调试固然就能提升开发效率,不过打包后的文件有时候你是不容易找到出错了的地方对应的源代码的位置的,Source Maps就是来帮咱们解决这个问题的。
经过简单的配置后,Webpack在打包时能够为咱们生成的source maps,这为咱们提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试。
在webpack的配置文件中配置source maps,须要配置devtool,它有如下四种不一样的配置选项,各具优缺点,描述以下:
正如上表所述,上述选项由上到下打包速度愈来愈快,不过同时也具备愈来愈多的负面做用,较快的构建速度的后果就是对打包后的文件的的执行有必定影响。
在学习阶段以及在小到中性的项目上,eval-source-map是一个很好的选项,不过记得只在开发阶段使用它,继续上面的例子,在webpack.config.js进行以下配置
// webpack.config.js module.exports = { devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项 entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" } }
cheap-module-eval-source-map方法构建速度更快,可是不利于调试,推荐在大型项目考虑da时间成本是使用。
想不想让你的浏览器监测你都代码的修改,并自动刷新修改后的结果,其实Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,能够实现你想要的这些功能,不过它是一个单独的组件,在webpack中进行配置以前须要单独安装它做为项目依赖
npm install --save-dev webpack-dev-server
devserver做为webpack配置选项中的一项,具备如下配置选项
继续把这些命令加到webpack.config.js的配置文件中,如今的配置文件以下所示:
module.exports = { devtool: 'eval-source-map', entry: __dirname + "/app/main.js", output: { path: __dirname + "/public", filename: "bundle.js" }, devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 colors: true,//终端中输出结果为彩色 historyApiFallback: true,//不跳转 inline: true//实时刷新 } }
Loaders是webpack中最让人激动人心的功能之一了。经过使用不一样的loader,webpack经过调用外部的脚本或工具能够对各类各样的格式的文件进行处理,好比说分析JSON文件并把它转换为JavaScript文件,或者说把下一代的JS文件(ES6,ES7)转换为现代浏览器能够识别的JS文件。或者说对React的开发而言,合适的Loaders能够把React的JSX文件转换为JS文件。
Loaders须要单独安装而且须要在webpack.config.js下的modules关键字下进行配置,Loaders的配置选项包括如下几方面:
test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)
loader:loader的名称(必须)
include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不须要处理的文件(文件夹)(可选);
query:为loaders提供额外的设置选项(可选)
继续上面的例子,咱们把Greeter.js里的问候消息放在一个单独的JSON文件里,并经过合适的配置使Greeter.js能够读取该JSON文件的值,配置方法以下:
webpack提供两个工具处理样式表,css-loader
和 style-loader
,两者处理的任务不一样,css-loader使你可以使用相似@import
和 url(...)
的方法实现 require()
的功能,style-loader将全部的计算后的样式加入页面中,两者组合在一块儿使你可以把样式表嵌入webpack打包后的JS文件中。
1.安装
//安装 npm install --save-dev style-loader css-loader
二、配置文件中使用
module.exports = { devtool:"sourcemap", entry:"./js/entry.js", output:{ filename:"bundle.js" }, module: { loaders:[ { test: /\.css$/, loader: 'style!css'//添加对样式表的处理 } ] }, }
注:感叹号的做用在于使同一文件可以使用不一样类型的loader
3.建立css文件,这里咱们给body添加一个简单的背景色pinkcss/style.css
文件
body{ background: pink; }
4.将上述css文件引入到入口entry.js
中。
require('./module-one.js'); require('./module-two.js'); require('../css/style.css'); // 引入css样式文件 document.write('It works.')
而后执行打包编译命令:
擦,怎么报错了-_-!!!
什么缘由呢?
原来引入的文件写法有问题,这里有两种改法:
在引入时须要加后缀loader
在配置文件中加loader后缀
第一种改法,修改引入文件:
require('./module-one.js'); require('./module-two.js'); // require('../css/style.css'); // 这样不加loader前缀标识会报错 require("!style-loader!css-loader!../css/style.css") // 载入 style.css document.write('It works.')
第二种改法,修改配置文件中的写法
module.exports = { devtool:"sourcemap", entry:"./js/entry.js", output:{ filename:"bundle.js" }, module: { loaders:[ { test: /\.css$/, // loader: 'style!css' //对这里进行修改,加后缀loader loader: 'style-loader!css-loader'//添加对样式表的处理 } ] }, }
而后咱们在用命令进行编译:
OK,没问题了,再看下加了pink的背景色的页面。
在开始以前,咱们先安装babel,用ES6的语法来进行测试,安装完以后,再进行文件的配置。
➜ webpack npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-stage-0 babel-runtime babel-plugin-transform-runtime
➜ webpack npm install vue vue-loader vue-html-loader vue-style-loader --save-dev
进行配置文件webpack.config.json
修改:
module.exports = { devtool:"sourcemap", entry:"./js/entry.js", output:{ filename:"bundle.js" }, module: { loaders:[ { test: /\.css$/, // loader: 'style!css'//添加对样式表的处理 loader: 'style-loader!css-loader'//添加对样式表的处理 }, { test:/\.js$/, loader:"babel-loader", exclude:/node_modules/ // 将这个目录忽略掉,将加快加载速度 }, { test:/\.vue$/, loader:"vue" } ] }, resolve:{ alias:{ 'vue$':'vue/dist/vue.js' } } };
新建js/components/heading.vue文件
<template> <div> <h1>{{ message }}</h1> </div> </template> <script> // 这里使用的是ES6的写法 export default{ data(){ return { message:'hello, vue' } } } </script>
在入口文件entry.js
中引入该文件:
require('./module-one.js'); require('./module-two.js'); require('../css/style.css'); // 这样不加loader前缀标识会报错 // require("!style-loader!css-loader!../css/style.css") // 载入 style.css document.write('It works.'); // vue 组件操做,这里使用ES6 babel语法 import Vue from 'vue'; Vue.component('Heading', require('./components/heading.vue')); new Vue({ el:"#app", }) // 或者使用下面这种方法加载组件 /** import Heading from './components/heading.vue'; new Vue({ el:"#app", components:{ Heading } }) */
最后不要忘记,在index.html中添加id为app的标示
<!-- index.html --> <html> <head> <meta charset="utf-8"> <title> webpack学习 </title> </head> <body> <h1>Webpack is very nice !</h1> <div id="app"> <!-- 这里添加的是Vue组件 --> <Heading></Heading> </div> <script src="bundle.js"></script> </body> </html>
以上就是在webpack中使用Vue组件的步骤。
下面是须要用到的包package.json
{ "name": "webpack", "version": "1.0.0", "description": "webpack learning", "main": "bundle.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Corwien", "license": "ISC", "devDependencies": { "babel-core": "^6.23.1", "babel-loader": "^6.3.2", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-es2015": "^6.22.0", "babel-preset-stage-0": "^6.22.0", "babel-runtime": "^6.23.0", "css-loader": "^0.26.2", "jquery": "^3.1.1", "style-loader": "^0.13.2", "vue": "^2.2.1", "vue-html-loader": "^1.2.4", "vue-loader": "^11.1.4" } }
git init
在.gitignore
文件中添加忽略的文件或文件夹名
node_modules
// 一、保存到暂存区: git add -A // 二、检查 Git 状态: git status // 3.保留改动并提交: git commit -m "Initial commit" // 4.将代码上传到github $ git remote add origin git@github.com:your_username/hello_laravel.git $ git push -u origin master
至此,示例代码被推送到GitHub上了。
本项目被推送到GitHub的地址:
https://github.com/corwien/we...
请看原文快速入门Webpack
注:本文转自快速入门Webpack