构建 webpack+jquery+es6+reactjs 自动化入坑

1,985 阅读3分钟
原文链接: azq.space

自己学习了一阵子webpack终于小有点成果,虽然是查阅了很多东西,也是趟过了很多坑;个人觉得reactjs+es6的项目适合webpack以及多页面的移动端项目;概念的东西我就在这里不赘述了,网上能查阅到很多东西

文件目录

  • 根目录
    • app //源文件
    • css
    • js
    • index.html
    • index.js //入口文件
    • package.json
    • webpack.config.js //配置文件
    • README.md //说明文档

安装包依赖

{
  "name": "webpack-html5",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "watch": "webpack --progress --colors --watch"//监听文件的变化并执行编译,npm run watch
  },
  "author": "azq",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer-loader": "^3.2.0",//css自动加浏览器前缀,w3c标准
    "babel-core": "^6.14.0",//编译js的
    "babel-loader": "^6.2.5",//编译js的
    "babel-preset-es2015": "^6.14.0",//编译es6到es5
    "babel-preset-react": "^6.11.1",//编译jsx
    "clean-webpack-plugin": "^0.1.10",//清空文件
    "css-loader": "^0.23.1",//压缩css
    "extract-text-webpack-plugin": "^1.0.1",//这个应该是不打包css用的
    "file-loader": "^0.8.5",//处理文件的
    "html-loader": "^0.4.3",//处理html的
    "html-webpack-plugin": "^2.9.0",//html模板
    "jquery": "^3.1.1",//jquery模块
    "less": "^2.6.0",//less核心
    "less-loader": "^2.2.2",//编译less
    "postcss-px2rem": "^0.3.0",//px转换rem
    "react": "^15.3.2",//react核心
    "react-dom": "^15.3.2",//react-dom核心
    "style-loader": "^0.13.0",//装载机
    "url-loader": "^0.5.7",//类似file-loader,可以设置文件大小转换url数据
    "webpack": "^1.12.13",
    "webpack-dev-server": "^1.16.1"
  }
}

webpack配置

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const ROOT_PATH = path.resolve(__dirname);//根目录
const APP_PATH = path.resolve(ROOT_PATH, 'app');//源文件目录
const BUILD_PATH = path.resolve(ROOT_PATH, 'build');目标输出目录
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const px2rem = require('postcss-px2rem');

module.exports = {
    entry: {//入口,默认index.js
        app:APP_PATH,
        vendor: ['jquery','react','react-dom']//单独打包的
    },
    output: {//输出配置
        path: BUILD_PATH,
        publicPath: "./",
        filename: 'bundle.js'
    },
    plugins: [
        new CleanPlugin('build'),//清空bulid
        new webpack.optimize.UglifyJsPlugin({
            compressor: {
                warnings: false,
            },
            except: ['$super', '
, 'exports', 'require'] //排除关键字 }), new webpack.optimize.OccurenceOrderPlugin(), new HtmlWebpackPlugin({ template: APP_PATH+'\\index.html', inject: 'true' }), new ExtractTextPlugin("styles.css"), new webpack.DefinePlugin({ 'process.env':{ 'NODE_ENV': JSON.stringify('production') } }), new webpack.ProvidePlugin({//提供全局 $: "jquery", jQuery: "jquery", "window.jQuery":"jquery", React:"react", ReactDom:"react-dom" }), new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),//将入口中的vendor打包 ], postcss: () => { return [px2rem({remUnit: 64})];//以64位基准去px 2 rem }, module: { loaders: [ {//压缩和px2rem test: /\.css$/, loader: ExtractTextPlugin.extract('style!css!postcss') },{//less的编译和加前缀 test: /\.less/, loader: ExtractTextPlugin.extract('css!autoprefixer!less') }, {//jsx的编译 test: /\.jsx?$/, exclude: /(node_modules|bower_components)/, loader: 'babel', query: { presets: ['react', 'es2015'] }, }, { //html模板加载器,可以处理引用的静态资源,默认配置参数attrs=img:src,处理图片的src引用的资源 //比如你配置,attrs=img:src img:data-src就可以一并处理data-src引用的资源了,就像下面这样 test: /\.html$/, loader: "html?-minimize&attrs=img:src img:data-src" }, { //文件加载器,处理文件静态资源 test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader?name=./fonts/[name].[ext]' }, { //图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求 //如下配置,将小于xxxbyte的图片转成base64码 test: /\.(png|jpg|gif)$/, loader: 'url-loader?limit=8192&name=./img/[name].[ext]' }, { test: /\.json$/, loader: 'file-loader?name=./[name].[ext]' }] } }

ps:注释可能有的不准确,希望自己去查询一下

入口文件

这里用了es6的语法,以及测试的demo里也是,如果不使用es6可以去掉相关es6编译的,然后如何里的代码用require来引用

import './css/base.less';
import './css/index.less';
import './js/comments.json';//用来模拟ajax的数据
import './js/ProductBox.jsx';

其他文件

ProductBox.jsx//这个代码是网上学reactjs的时候看到的,然后做了一些修改

class Comment extends React.Component {
    render() {
        return (
            
{this.props.children}
- {this.props.author}
); } } class CommentForm extends React.Component { handleSubmit(e) { e.preventDefault(); const author = this.refs.author.value.trim(); const body = this.refs.body.value.trim(); const form = this.refs.form; this.props.onSubmit({author: author, body: body}); form.reset(); } render() { return ( {this.handleSubmit(e)}}> ); } } class CommentList extends React.Component { render() { var commentsNode = this.props.comments.map((comment, index) => { return {comment.body} }); return (
{commentsNode}
); } } class CommentBox extends React.Component { constructor(props) { super(); this.state = { comments: props.comments || [] }; } loadDataFromServer() { $.ajax({ url: this.props.url, dataType: "json", success: comments => { this.setState({comments: comments}); }, error: (xhr, status, err) => { console.log(err.toString()); } }); } componentDidMount() { this.loadDataFromServer(); } handleNewComment(comment) { const comments = this.state.comments; const newComments = comments.concat([comment]); this.setState({comments: newComments}); setTimeout(() => { $.ajax({ url: this.props.url, dataType: "json", type: "POST", data: comment, success: comments => { this.setState({comments: comments}); }, error: (xhr, status, err) => { console.log(err.toString()); this.setState({comments: comments}); } }); }, 2000); } render() { return (

Comments

this.handleNewComment(comment)}/>
); } } let box = ReactDom.render(//这里的ReactDom需要webpack配置里把react-dom取出来,因为第三方的包都单独打包了,不在一个里面,这里觉得是可以优化但是还无从下手 , document.getElementById('content') );

时间点

需求

  • [x] css中px2rem,并压缩css
  • [x] js压缩 混淆,模块化
  • [x] 自动添加到html中js,css引用
  • [x] 小于8k的自动转换base64

9.6 需求

  • [ ] 图片数据打包到js文件中
  • [x] 替换js css html 中的图片路径

9.7 需求

  • [ ] 生成大于8k的图片数据与音频列表与预加载结合

9.20

  • [x] css属性自动加前缀

9.20

  • [x] 修改代码自动编译 npm run watch

9.28

  • [x] es6编译
  • [x] react编译
  • [x] 第三方库打包到一起

this.refs.author.getdomnode()失效,React v0.14 可以直接this.refs.author获取dom

有的没有实现,自己也没有仔细想,先把眼前网上能查到的实现了,后续还会继续更新

其他扯

公众号

BigCan

我们的主页