webpack能够看作是模块打包机:它作的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。css
注意: 目前最新为webpack2.0版本,与1.0有一些出入html
npm init
npm install webpack --save-dev
npm install style-loader css-loader stylus-loader stylus --save-dev
npm install --save-dev postcss-loader autoprefixer
// 该配置基于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 代码以下node
require('./common/css/style.css'); require('./common/css/stylus.styl');react
经过webpack-dev-server实现页面的自动刷新。webpack
首先安装webpack-dev-servergit
npm install --save-dev webpack-dev-server
而后修改package.json配置文件中:github
"scripts": { "start": "webpack-dev-server", "build": "webpack" }
使用npm start 启动服务。npm的 start是一个特殊的脚本名称,它的特殊性表如今,在命令行中使用npm start就能够执行相关命令,若是对应的此脚本名称不是start,想要在命令行中运行时,须要这样用npm run {script name},因此打包命令修改成npm run build。web
这里若是使用webpack-dev-server 命令来启动就必须全局安装 devServer:npm
npm install webpack-dev-server -g
在webpack的配置文件中能够对devServer进行配置json
// 配置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都不该该出如今生产的配置中)。详细能够参考https://segmentfault.com/a/1190000006151512这篇文章
module.exports = { devtool: 'eval-source-map',//配置生成Source Maps,选择合适的选项 .... } }
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/ //须要排除的目录 }
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 来尝试一下。。参考http://www.tuicool.com/articles/22aQ7vu
经过以上步骤基本的开发环境就搭建完毕了,那么实际上在生产环境里可能会有其余的要求,例如分离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;
如今分别介绍几个经常使用的插件:详情参考 https://github.com/webpack/docs/wiki/list-of-plugins
提取公共模块插件(webpack内置) CommonsChunkPlugin
清除文件夹: clean-webpack-plugin
运用[hash]使得产生的文件名带有哈希值,合理使用缓存。
至此大体的开发以及生产环境已经搭建完毕。
项目地址: https://github.com/Dyzzi/webpack-demo-project