这两天学习了一些webpack的知识,loaders+plugins真的很强大!不过配置起来也很复杂,看了一些文章,本身也写了项目练手,写下来加深本身的印象。css
首先,很是很是推荐的几篇文章,初学者必定要看!
<入门Webpack,看这篇就够了>
http://www.jianshu.com/p/42e1...
(标题一点也不夸张,很是适合0基础)
<Webpack傻瓜式指南>
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
(这个系列有三篇文章,第三章是一个webpack+react的小项目,跟着作一遍会颇有收获~)html
另外,也推荐看一下阮一峰es6书中module这一章,弄清楚export/import/export default等等命令,毕竟webpack的各个模块是靠export/import/require(commonjs)连接起来的,因此这些都要掌握。node
具体到项目的话,webpack有几个比较基本的概念:
一、loaders:经过不一样的loaders,webpack能够处理各式各样的文件,而后打包到一个文件中(好比bundle.js);
二、plugins:plugins是为了拓展webpack的功能的,和loaders不一样的是,loader是用来处理单个文件的(好比json-loader处理.json,sass-loader处理.scss),可是plugins是直接对整个构建过程进行处理(好比自动生成html文件的html-webpack-plugin);
三、others: 这些我也不知道要归到哪里去,可是在配置中也是必不可少,包括webpack-dev-server/source-map等等,后面会具体说;
四、配置文件:我这个小项目包括的文件有.babelrc(用来处理babel),webpack.config.js(webpack项目基础配置文件),package.json(这个文件会记录全部的devDependencies)。react
而后咱们就一项一项来分析吧:jquery
1) style-loader / css-loader / sass-loaderwebpack
这几个loader用来处理.css和.scss文件,一块儿安装用空格隔开:es6
$ npm install --save-dev style-loader css-loader sass-loader
同时修改webpack.config.js:web
module: { loaders: [ { test: /\.scss$/, //loaders是依靠正则表达式来测试这个文件是否是这个loader来处理,因此test不能少 loaders: ['style-loader','css-loader','sass-loader'], //"-loader"必定要写,否则会报错 //loaders的处理顺序是从右向左,就是会先用sass-loader,其次css-loader,再次style-loader }
2) url-loader正则表达式
这个loader是用来处理url连接,就是图片或者其余静态文件。
安装:npm
$ npm install --save-dev url-loader
webpack.config.js (写在module里):
{ test: /\.(png|jpq)$/, loader: 'url? limit = 40000' }
3) json-loader
安装和配置和以前同样~用来处理json文件
4) babel相关的loaders:
这个包括的就比较多,有babel-core/babel-loader/babel-preset-es2015/babel-preset-react,后面两个是为了写es6和react服务。
//webpack.config.js { test: /\.jsx$/, loader:'babel-loader', include: APP_PATH, //这个include是说只对这里面的文件负责,还有一个对应的exclude,就是忽略范围内的文件, 好比:exclude: './node_modules/'; }
另外由于babel须要写的选项比较多,能够配一个.babelrc在根目录下:
//.babelrc { 'presets':['react','es2015'], } }
以上就是用的比较多的loaders,配完这些webpack就能够处理json/sass/es6啦~
1) html-webpack-plugin
这个插件的做用就是自动生成html(其实也能够本身写,就是加了个bundle.js的script而已,不过感受比较酷):
plugins安装好了以后要放在webpack.config.js的plugins的数组里,不要写在modules里呀~
//webpack.config.js plugins: [ new HtmlWebpackPlugin({ //在最前面先定义下HtmlWebpackPlugin-- //var HtmlWebpackPlugin = require('html-webpack-plugin'); title: 'searchBar', //配合html-webpack-plugin的配置 }) ],
2) react-transform-hrm
HMR是一个webpack插件,它让你能浏览器中实时观察模块修改后的效果,可是若是你想让它工做,须要对模块进行额外的配额;
Babel有一个叫作react-transform-hrm的插件,能够在不对React模块进行额外的配置的前提下让HMR正常工做;
安装:
$ npm install --save-dev babel-plugin-react-transform react-transform-hmr
配置:
//webpack.config.js (plugins里) new webpack.HotModuleReplacementPlugin();
而后修改下.babelrc:
{ "presets": ["react", "es2015"], "env": { "development": { "plugins": [["react-transform", { "transforms": [{ "transform": "react-transform-hmr", "imports": ["react"], "locals": ["module"] }] }]] } } }
这样在使用react的时候就能够热加载模块了~
3)UglifyJsPlugin:
压缩JS代码;
4)ExtractTextPlugin:
分离CSS和JS文件;
以上两个插件此次没有用,先记下来下次用过了再来补~
1) webpack-dev-server
用来构建本地开发的服务器,可让浏览器监测代码的修改,并自动刷新修改后的结果;
安装:
$npm --save-dev webpack-dev-server
webpack-dev-server有如下几个配置选项:
contentBase:默认webpack-dev-server会为根文件夹提供本地服务器,若是想为另一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到“public"目录)
port:设置默认监听端口,若是省略,默认为”8080“
inline:设置为true,当源文件改变时会自动刷新页面
historyApiFallback:在开发单页应用时很是有用,它依赖于HTML5 history API,若是设置为true,全部的跳转将指向index.html
//webpack.config.js devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true//实时刷新 }
//package.json "scripts": { "start": "webpack-dev-server --inline", }
而后就能够用http://localhost:8080/index.html预览项目啦~
2)source-map:
source maps提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试。
在学习阶段和写中、小型项目的时候,用eval-source-map,若是是开发大型项目能够用cheap-module-eval-source-map,会更快。
//webpack.config.js devtool: 'eval-source-map',
3) 第三方库:
这个就包括一些咱们比较了解的好比react/react-dom/jquery/moment/bootstrap等等啦,配置起来也很方便,首先是安装:
$npm --save-dev jquery moment react react-dom $npm install bootstrap@4.0.0-alpha.2 --save-dev
而后在你须要的js文件里引用这些库:
import React from 'react'; import ReactDOM from 'react-dom'; var $ = require('jquery'); var moment = require('moment');
而后就能够愉快地写各类js、jsx文件啦~
最后咱们来说一讲几个配置文件的问题:
1) webpack.config.js
上面提到的都是各类肢解,我此次的config文件是这样的:
var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ROOT_PATH = path.resolve(__dirname); var APP_PATH = path.resolve(ROOT_PATH, 'app'); var BUILD_PATH = path.resolve(ROOT_PATH, 'build'); module.exports = { devtool: 'eval-source-map', entry: __dirname + '/app/index.jsx', //webpack的入口文件只有一个,因此写的全部components甚至包括css/json什么的,都要引用在这里 output:{ path: __dirname +'/public', filename: 'bundle.js', }, //我这边是新建了一个folder叫public,用来放index.html和bundle.js devServer: { contentBase: "./public",//本地服务器所加载的页面所在的目录 historyApiFallback: true,//不跳转 inline: true//实时刷新 }, plugins: [ new HtmlWebpackPlugin({ title: 'searchBar', //配合html-webpack-plugin的配置 }) ], module: { loaders: [ { test: /\.scss$/, loaders: ['style-loader','css-loader','sass-loader'], },{ test: /\.(png|jpq)$/, loader: 'url? limit = 40000' },{ test: /\.jsx$/, loader:'babel-loader', include: APP_PATH, }] }, resolve:{ extensions: ['','.js', '.jsx'] }, };
2) package.json
这个文件会在你最开始npm init的时候就生成,一路回车就能够,后来均可以改~
{ "name": "serach-bar", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack-dev-server --progress --profile --colors --hot", "build": "webpack --progress --profile --colors", "test": "karma start" }, //scripts这边能够改一下,改start能够,在终端用npm start,上面有例子~这边的dev要改的话在终端的命令是'npm run dev; "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.22.1", "babel-loader": "^6.2.10", "babel-plugin-react-transform": "^2.0.2", "babel-preset-es2015": "^6.22.0", "babel-preset-react": "^6.22.0", "babel-preset-react-hmre": "^1.1.1", "bootstrap": "^4.0.0-alpha.2", "css-loader": "^0.26.1", "file-loader": "^0.10.0", "html-webpack-plugin": "^2.28.0", "jquery": "^3.1.1", "jshint": "^2.9.4", "jshint-loader": "^0.8.3", "json-loader": "^0.5.4", "node-sass": "^4.5.0", "react": "^15.4.2", "react-dom": "^15.4.2", "react-transform-catch-errors": "^1.0.2", "react-transform-hmr": "^1.0.4", "redbox-react": "^1.3.3", "sass-loader": "^4.1.1", "style-loader": "^0.13.1", "url-loader": "^0.5.7", "webpack": "^2.2.1", "webpack-dev-server": "^2.3.0" } }
装了不少dev,其实用不着那么多哈哈~
3) .babelrc
{ 'presets':['react','es2015'], 'env':{ 'development':{ 'presets':['react-hmre'] } } }
ok,这样就差很少啦~另外还要注意的是index.jsx/index.js,全部的components都要引用过来,css/scss也是,css文件的话最好有一个main.css进行整合,这样不会漏掉。
看一眼此次的index.jsx:
// '注意这些import import '../node_modules/bootstrap/scss/bootstrap.scss'; import './main.scss'; import React from 'react'; import ReactDOM from 'react-dom'; import Search from './components/search'; import Plist from './components/plist'; class App extends React.Component{ constructor(props){ super(props); this.state={'keyword':''}; this.refreshKeyword = this.refreshKeyword.bind(this); } refreshKeyword(name){ this.setState({'keyword':name}); } render(){ return ( <div className = 'container'> <section className = 'jumbotron'> <h3 className ='jumbotron-heading'>Search Github Users</h3> <Search sendAction = {this.refreshKeyword} /> </section> <Plist keyword={this.state.keyword} /> </div> ) } }; const app = document.createElement('div'); document.body.appendChild(app); ReactDOM.render(<App />, app);
恩,差很少就是这样啦~~项目初始化的时候不要忘记npm install --save-dev webpack哦!coding愉快!