简单的配置:
使用前需要全局安装webpcak
1.webpack.config.js配置文件
module.exports = { entry:[ './app/main.js' ], output: { path: __dirname + '/assets/', publicPath: "/assets/", filename: 'bundle.js' } };
entry:定义了打包后的入口文件,数组中的所有文件会按顺序打包。每个文件进行依赖的递归查找,直到所有相关模块都被打包。
output:定义了输出文件的位置,其中常用的参数包括:
path: 打包文件存放的绝对路径
publicPath: 网站运行时的访问路径
filename: 打包后的文件名
2. 进阶使用:
首先准备一下配置文件:
var webpack = require('webpack'); module.exports = { entry:{ page: "./src/app.js" }, output: { path: './build', filename: "bundle.js" }, module: { loaders: [ {test:/\.js$/,exclude: /node_modules/,loader:''},//加载器在这里 //下面我们会在这里增加 ] } };
1):对es6的支持:
# 1.支持es6 ```bash npm i --save-dev babel-core babel-loader babel-preset-es2015 ``` webpack.config.js ```javascript { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' } ``` .babelrc ```javascript { "presets": [ "es2015" ] } ```
2).对react的支持:
# 2. 支持React语法 ```javascript {test:/\.jsx$/,exclude: /node_modules/,loader:'jsx-loader?harmony'} ``` 入口文件app.js ```javascript var React = require('react'); var ReactDOM = require('react-dom'); var HelloMessage = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } }); ReactDOM.render( <HelloMessage name="John" />, document.getElementById('example') ); ```
3).React和es6同时支持
# 3. React和es6同时支持 - 安装 ```bash npm i --save-dev babel-preset-react ``` 注意:.babelrc文件和上面的是一样也是必须的。 webpack.config.js ```javascript {test:/\.jsx?$/,exclude: /node_modules/,loader: 'babel', query: {presets: ['es2015', 'react']}}, //同时支持es6 react 或者下面的写法都可以 {test:/\.jsx?$/,exclude: /node_modules/,loader:'babel?presets[]=react,presets[]=es2015'}, //同时支持es6 react ``` 使用React,es6语法 ```javascript import React from 'react'; import ReactDOM from 'react-dom'; class HelloMessage extends React.Component { render() { return <h1> Hello { this.props.name } </h1>; } } ReactDOM.render( <HelloMessage name="zry" />, document.getElementById('example') );
4).css/sass
## css/sass - 安装 ```bash npm i --save-dev style-loader css-loader sass-loader node-sass ``` - webpack.config.js ```javascript { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ``` 使用很简单 ```javascript import "./home/home.css"; import "./home/home.scss"; ``` ## css文件可以独立出来 ``` npm i --save-dev extract-text-webpack-plugin ``` 配置 ``` /*下面两行的作用是分离css*/ { test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass
5):图片
## 图片加载 ```bash npm i --save-dev url-loader ``` 配置webpack.config.js ``` {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'} ``` 意思是大于8192kb的图片会以base64的形式加载 使用: ``` <img src={require("./imgs/rect.png")}/> //或者在css中直接使用 background: url(imgs/toolbar.png) no-repeat; ```
6):路径管理
## path路径管理 有时候在配置文件中经常会用到路径管理 ``` npm i --save-dev path ``` 在配置文件中 ``` var path = require('path'); output: { path: path.resolve(__dirname, 'output'), }, ```
7):插件、热加载等配置
package.json ```javascript { "name": "react-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server --hot --progress --colors", "build": "webpack --progress --colors" }, "repository": { "type": "git", "url": "zry" }, "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.18.0", "babel-loader": "^6.2.7", "babel-preset-es2015": "^6.18.0", "babel-preset-react": "^6.16.0", "css-loader": "^0.25.0", "jsx-loader": "^0.13.2", "node-sass": "^3.10.1", "react": "^15.3.2", "react-dom": "^15.3.2", "sass-loader": "^4.0.2", "style-loader": "^0.13.1", "webpack": "^1.13.3" } } ``` webpack.config.js ```javascript var webpack = require('webpack'); module.exports = { entry:{ page: "./src/app.js" }, output: { path: './build', filename: "bundle.js" }, module: { loaders: [ // { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },//支持es6 // {test:/\.jsx?$/,exclude: /node_modules/,loader:'jsx-loader?harmony'},//支持react // {test:/\.jsx?$/,exclude: /node_modules/,loader:'babel?presets[]=react,presets[]=es2015'},//同时支持es6 react或者 {test:/\.jsx?$/,exclude: /node_modules/,loader: 'babel', query: {presets: ['es2015', 'react']}},//同时支持es6 react {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'}, /*下面两行的作用是分离css*/ /*{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass加载器*/ { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ] }, resolve: { extensions: ['', '.js', '.json'] }, plugins: [ // new ExtractTextPlugin("output/[name].css"),//独立css文件 new webpack.NoErrorsPlugin() ], devtool: 'source-map' }; ``` 别忘了.babelrc文件 ```javascript { "presets": [ "es2015" ] } ```
8):react热加载
webpack-dev-server支持热插拔(热替换 HRM),使用HRM功能也有两种方式:命令行方式(推荐)和Node.js API 方式。 ## 6.1 Node.js API方式 Node.js API方式需要做三个配置: 1) 把`webpack/hot/dev-server`加入到webpack配置文件的entry项; 2) 把`new webpack.HotModuleReplacementPlugin()`加入到webpack配置文件的plugins项; 3) 把`hot:true`加入到webpack-dev-server的配置项里面。 使用 react 编写代码时,能让修改的部分自动刷新。但这和自动刷新网页是不同的,因为 hot-loader 并不会刷新网页,而仅仅是替换你修改的部分 - 安装 ```bash npm i --save-dev react-hot-loader webpack-dev-server ``` - 修改.babelrc ```javascript { "presets": [ "es2015" ], "plugins":["react-hot-loader/babel"] } ``` - 修改webpack.config.js ```javascript var webpack = require('webpack'); module.exports = { //修改:entry entry: [ "webpack-dev-server/client?http://127.0.0.1:3000", "webpack/hot/only-dev-server", "./src/app.js" ], //修改:output output: { path: __dirname, filename: "build/bundle.js", publicPath: "/build" }, module: { loaders: [ { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } }, //同时支持es6 react {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'}, /*下面两行的作用是分离css*/ /*{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") }, { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass加载器*/ { test: /\.css$/, loader: "style!css" }, { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器 ] }, resolve: { extensions: ['', '.js', '.json'] }, plugins: [ // new ExtractTextPlugin("output/[name].css"),//独立css文件 new webpack.NoErrorsPlugin(), //允许错误不打断程序 new webpack.HotModuleReplacementPlugin() //增加:webpack热替换插件 ], devtool: 'source-map' }; ``` - 增加server.js文件 ```javascript var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.config'); new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, historyApiFallback: true }).listen(3000, 'localhost', function(err, result) { if (err) { return console.log(err); } console.log('Listening at http://localhost:3000/') });
说了这么多来一个比较综合性的配置:
//config.js 开发环境 //当webpack is not defined时要引入webpack var webpack = require('webpack'); //引入html-webpack-plugin插件 var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode:'development', //webpack4. has using webpack-cli entry: __dirname+'/app/main.js', devtool:'eval-source-map',//编译文件和源文件,使得代码可读性高 output:{ path:__dirname+'/build', filename:'bundle.js' // }, //webpack 本地服务 devServer:{ contentBase:'./build',// localhost dist historyApiFallback:true,//not href inline:true,// refresh port:8000 }, //模块 功能 module:{ rules:[ // babel | js |babel-plugin-react-transform //插件可以实现reac组建的热更新 { test:/(\.jsx|\.js)$/, use:{ //when use this babel probably install broserslist loader:"babel-loader" // use .babelrc instead this options // options:{ // presets:[ // "env","react" // ] // } }, exclude:/node_modules/ }, //css { test:/(\.css|\.scss)$/, use:[ { loader:'style-loader' }, { loader:'css-loader', options:{ //css modules. modules:true, localIdentName:'[name]__[local]--[hash:base64:5]' } }, { //css 预处理平台 需要添加postcss.config.js 自动添加不同浏览器前缀(-webkit-/-moz-等) loader:'postcss-loader' } ] }, //打包图片资源 { test:/\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader:'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' }, { test:/\.png$/, loader:"file-loader?name=images/[hash:8].[name].[ext]" } ] }, //插件使用 plugins:[ // 打包 版权插件 new webpack.BannerPlugin('版权所有,翻版必究'), new HtmlWebpackPlugin({ //创建插件实例 传入相关参数,当模版文件发生变化时 //对应的构建出的html文件也会随之发生变化 template:__dirname+"/app/index.tmpl.html" }), //热加载插件 new webpack.HotModuleReplacementPlugin() ] };
//webpack.production.config.js 生产环境 //产品构建阶段 var path = require('path'); var webpack =require('webpack'); //Html-webpack-plugin //cnpm i --save-dev html-webpack-plugin var HtmlWebpackPlugin = require('html-webpack-plugin'); //mini-css-extract-plugin const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //clean-webpack-plugin var CleanWebpackPlugin = require('clean-webpack-plugin'); //webpack-uglify-js-plugin var webpackUglifyJsPlugin = require('webpack-uglify-js-plugin'); //modules exports module.exports = { mode:'production', entry:__dirname+"/app/main.js", devtool:'none',// 产品阶段以减少代码量 output:{ path:__dirname+'/build', filename:'bundle-[hash].js' }, //webserver //npm i --save-dev webpack-dev-server devServer:{ contentBase:'./build', historyApiFallBack:true, port:8080, inline:true, hot:true }, //modules module:{ rules: [ //js | jsx... //cnpm i --save-dev babel-loader babel-core babel-preset-env babel-preset-react //if hot react-- cnpm i --save-dev babel-plugin-react-transform //important .babelrc { test:/(\.js|\.jsx)$/, use:{ loader:"babel-loader" //options:[]... if has .babelrc can instead }, exclude:/node_modules/ }, //css //npm i --save-dev css-loader style-loader postcss-loader autoprefixer { test:/(\.css|\.scss|\.less)$/, //如果loader多多情况下,这样写 use:[ MiniCssExtractPlugin.loader, "css-loader" // { // loader:"style-loader" // }, // { // loader:"css-loader", // //css modules // options:{ // modules:true, // localIdentName:'[name]__[local]--[hash:base64:5]' // } // }, // //css preix // { // loader:'postcss-loader' // //need set postcss.config.js require('autoprefixer') // } ], exclude:/node_modules/ }, //打包图片资源 { test:/\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader:'url-loader?limit=8192&name=images/[hash:8].[name].[ext]' }, { test:/\.png$/, loader:"file-loader?name=images/[hash:8].[name].[ext]" } ] }, //plugins plugins:[ //banner new webpack.BannerPlugin('版权所有,翻版必究 !'), //html webpack plugin new HtmlWebpackPlugin({ template:__dirname+'/app/index.tmpl.html' }), //webpack hot plugin new webpack.HotModuleReplacementPlugin(), //product plugin new webpack.optimize.OccurrenceOrderPlugin(), new webpackUglifyJsPlugin({ cacheFolder: path.resolve(__dirname, 'public/cached_uglify/'), debug: true, minimize: true, sourceMap: false, output: { comments: false }, compressor: { warnings: false } }), new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: "css/[name].[chunkhash:8].css", chunkFilename: "[id].css" }), //clean new CleanWebpackPlugin(['build','public'], { root:__dirname, verbose:true, dry:false, exclude:[] }) ] };
//.babel { "presets": ["react", "env"], "env": { "development": { "plugins": [["react-transform", { "transforms": [{ "transform": "react-transform-hmr", "imports": ["react"], "locals": ["module"] }] }]] } } }
//postcss.config.js //浏览器前缀自动检测插件 module.exports = { plugins:[ require('autoprefixer') ] }
// package.json
{ "name": "ajaxs", "version": "0.0.1", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "./node_modules/.bin/webpack-cli", "server": "webpack-dev-server --open", "product": "./node_modules/.bin/webpack-cli --config ./webpack.production.config.js --progress --profile --colors" }, "author": "", "license": "ISC", "devDependencies": { "autoprefixer": "^8.1.0", "babel-core": "^6.26.0", "babel-loader": "^7.1.4", "babel-plugin-react-transform": "^3.0.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "browser-sync": "^2.23.6", "browserslist": "^3.2.0", "clean-webpack-plugin": "^0.1.19", "css-loader": "^0.28.11", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.11", "html-webpack-plugin": "^3.0.6", "mini-css-extract-plugin": "^0.2.0", "post-loader": "^2.0.0", "postcss-loader": "^2.1.2", "react": "^16.2.0", "react-dom": "^16.2.0", "react-transform-hmr": "^1.0.4", "style-loader": "^0.20.3", "url-loader": "^1.0.1", "webpack": "^4.1.1", "webpack-cli": "^2.0.11", "webpack-dev-server": "^3.1.1", "webpack-uglify-js-plugin": "^1.1.9" } }
未完待续~
爱前端 爱设计 爱生活