mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
initial commit
This commit is contained in:
commit
4a2a343e41
11 changed files with 13640 additions and 0 deletions
12
.babelrc
Executable file
12
.babelrc
Executable file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"presets": ["env", "react","stage-2"],
|
||||
"plugins": [
|
||||
"ramda",
|
||||
"lodash",
|
||||
"react-hot-loader/babel",
|
||||
["transform-runtime", {
|
||||
"polyfill": false,
|
||||
"regenerator": true
|
||||
}]
|
||||
]
|
||||
}
|
73
.eslintrc
Executable file
73
.eslintrc
Executable file
|
@ -0,0 +1,73 @@
|
|||
{
|
||||
"extends": "airbnb",
|
||||
"parser": "babel-eslint",
|
||||
"plugins": [
|
||||
"react",
|
||||
"jsx-a11y",
|
||||
"import",
|
||||
"jest"
|
||||
],
|
||||
"rules": {
|
||||
"quotes": 1,
|
||||
"comma-dangle": 0,
|
||||
"no-restricted-syntax": 1,
|
||||
"new-cap": 1,
|
||||
"no-continue": 1,
|
||||
"no-underscore-dangle": 1,
|
||||
"global-require": 1,
|
||||
"react/no-multi-comp": 1,
|
||||
"react/jsx-filename-extension": 0,
|
||||
"camelcase": 1,
|
||||
"import/no-unresolved": 1,
|
||||
"import/prefer-default-export": 0,
|
||||
"import/extensions": 1,
|
||||
"no-return-assign": 1,
|
||||
"max-len": 1,
|
||||
"jsx-a11y/no-static-element-interactions": 0,
|
||||
"jsx-a11y/click-events-have-key-events": 0,
|
||||
"jsx-a11y/interactive-supports-focus": 0,
|
||||
"arrow-parens": 0,
|
||||
"jsx-a11y/no-autofocus": 0,
|
||||
"react/jsx-closing-tag-location": 0,
|
||||
"prefer-promise-reject-errors": 0,
|
||||
"jsx-a11y/mouse-events-have-key-events": 0
|
||||
},
|
||||
"globals": {
|
||||
"document": false,
|
||||
"window": false,
|
||||
"HTMLInputElement": false,
|
||||
"HTMLDivElement": false,
|
||||
"Headers": false,
|
||||
"FormData": false,
|
||||
"WebSocket": true,
|
||||
"Element": true,
|
||||
"localStorage": true,
|
||||
},
|
||||
"env": {
|
||||
"jest/globals": true
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"webpack": {
|
||||
"webpack.config.js": {
|
||||
"resolve": {
|
||||
"alias": {
|
||||
"$components": "src/components",
|
||||
"$containers": "src/containers",
|
||||
"$constants": "src/constants",
|
||||
"$sprites": "src/sprites",
|
||||
"$config": "src/config",
|
||||
"$styles": "src/styles",
|
||||
"$redux": "src/redux",
|
||||
"$utils": "src/utils"
|
||||
},
|
||||
|
||||
"extensions": [".js", ".jsx", ".scss"],
|
||||
|
||||
"modules": ["src", "node_modules"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
23
.flowconfig
Normal file
23
.flowconfig
Normal file
|
@ -0,0 +1,23 @@
|
|||
[options]
|
||||
module.system.node.resolve_dirname=node_modules
|
||||
module.system.node.resolve_dirname=src
|
||||
module.name_mapper='^$redux/\([-a-zA-Z0-9$_/]+\)$' -> '<PROJECT_ROOT>/src/redux/\1'
|
||||
module.name_mapper='^components\/\(.*\)$' ->'<PROJECT_ROOT>/src/components/\1'
|
||||
module.name_mapper='^containers\/\(.*\)$' ->'<PROJECT_ROOT>/src/containers/\1'
|
||||
module.name_mapper='^constants\/\(.*\)$' ->'<PROJECT_ROOT>/src/constants/\1'
|
||||
module.name_mapper='^sprites\/\(.*\)$' ->'<PROJECT_ROOT>/src/sprites/\1'
|
||||
module.name_mapper='^config\/\(.*\)$' ->'<PROJECT_ROOT>/src/config/\1'
|
||||
module.name_mapper='^styles\/\(.*\)$' ->'<PROJECT_ROOT>/src/styles/\1'
|
||||
module.name_mapper='^utils\/\(.*\)$' ->'<PROJECT_ROOT>/src/utils/\1'
|
||||
|
||||
[ignore]
|
||||
.*/node_modules
|
||||
.*/node_modules/styled-components/.*
|
||||
|
||||
[include]
|
||||
public
|
||||
../node_modules/
|
||||
|
||||
[libs]
|
||||
flow-libs/
|
||||
|
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
/node_modules
|
||||
/dist
|
||||
/npm-debug.log
|
||||
/.idea
|
||||
/coverage
|
||||
/coverage/*
|
||||
/flow-coverage
|
||||
/flow-coverage/*
|
||||
.vscode
|
||||
.DS_Store
|
||||
yarn-error.log
|
||||
.awcache
|
||||
|
||||
# Bundle
|
||||
*.js.map
|
12973
package-lock.json
generated
Normal file
12973
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
69
package.json
Normal file
69
package.json
Normal file
|
@ -0,0 +1,69 @@
|
|||
{
|
||||
"name": "orchid_map",
|
||||
"sideEffects": false,
|
||||
"version": "0.0.0",
|
||||
"description": "Beta Map",
|
||||
"main": "./src/js/index.js",
|
||||
"scripts": {
|
||||
"start": "NODE_ENV=development webpack-dev-server --mode development --hot --open --inline --progress"
|
||||
},
|
||||
"author": "Grigory Chervoplyas",
|
||||
"license": "ISC",
|
||||
"keywords": [],
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.0.0-beta.54",
|
||||
"@babel/preset-env": "^7.0.0-beta.54",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-eslint": "^8.2.3",
|
||||
"babel-loader": "^7.1.4",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1",
|
||||
"css-loader": "^0.28.11",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-config-airbnb": "^16.1.0",
|
||||
"eslint-import-resolver-babel-module": "^4.0.0",
|
||||
"eslint-import-resolver-webpack": "^0.9.0",
|
||||
"eslint-loader": "^2.0.0",
|
||||
"eslint-plugin-babel": "^5.0.0",
|
||||
"eslint-plugin-flowtype": "^2.46.2",
|
||||
"eslint-plugin-import": "^2.11.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.0.3",
|
||||
"eslint-plugin-react": "^7.7.0",
|
||||
"file-loader": "^1.1.11",
|
||||
"flow-bin": "^0.73.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"style-loader": "^0.21.0",
|
||||
"webpack": "^4.6.0",
|
||||
"webpack-cli": "^2.0.15",
|
||||
"webpack-dev-server": "^3.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"clean-webpack-plugin": "^0.1.9",
|
||||
"history": "^4.7.2",
|
||||
"leaflet": "^1.3.3",
|
||||
"react": "^16.3.2",
|
||||
"react-dom": "^16.3.2",
|
||||
"react-hot-loader": "^4.1.1",
|
||||
"regenerator-runtime": "^0.11.1",
|
||||
"scrypt": "^6.0.3",
|
||||
"styled-components": "^3.2.6",
|
||||
"styled-theming": "^2.2.0",
|
||||
"webpack-git-hash": "^1.0.2"
|
||||
},
|
||||
"flow-coverage-report": {
|
||||
"includeGlob": [
|
||||
"src/**/*.js",
|
||||
"src/**/*.jsx"
|
||||
],
|
||||
"type": [
|
||||
"text",
|
||||
"html",
|
||||
"json"
|
||||
]
|
||||
}
|
||||
}
|
12
src/containers/App.jsx
Normal file
12
src/containers/App.jsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import { Map } from "$containers/Map";
|
||||
|
||||
export class App extends React.Component {
|
||||
render(){
|
||||
return (
|
||||
<div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
29
src/index.js
Normal file
29
src/index.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { App } from '$containers/App';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { ConnectedRouter } from 'react-router-redux';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
|
||||
// import { configs } from '$constants/moment';
|
||||
import configureStore, { history } from '$redux/store';
|
||||
|
||||
const { store, persistor } = configureStore();
|
||||
|
||||
// import './js/common';
|
||||
// import './js/script';
|
||||
import './css/style.css';
|
||||
|
||||
export const Index = () => (
|
||||
<Provider store={store}>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<ConnectedRouter history={history}>
|
||||
<App />
|
||||
</ConnectedRouter>
|
||||
</PersistGate>
|
||||
</Provider>
|
||||
);
|
||||
|
||||
ReactDOM.render(<Index />, document.getElementById('index'));
|
82
src/parts/map.js
Normal file
82
src/parts/map.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
import L from "leaflet";
|
||||
|
||||
import 'leaflet-editable';
|
||||
import 'leaflet.markercluster';
|
||||
import 'leaflet.markercluster.webpack';
|
||||
import 'leaflet-geometryutil';
|
||||
|
||||
import { mapStyles } from "$constants/mapStyles";
|
||||
|
||||
import { stickers } from "$constants/stickers";
|
||||
|
||||
import { updateMarks } from "$utils/updater";
|
||||
import { bindPolyEvents, preparePoly } from "$utils/poly";
|
||||
|
||||
// В этой штуке мы храним точки и выноски, их связки и всё такое
|
||||
const point_array = {
|
||||
points: L.layerGroup(),
|
||||
vectors: L.layerGroup(),
|
||||
handles: L.layerGroup(),
|
||||
pairs: {},
|
||||
point_to_id: {},
|
||||
id_to_point: {},
|
||||
savedata: {}
|
||||
};
|
||||
|
||||
const points = L.layerGroup();
|
||||
|
||||
let mode = "none";
|
||||
let current_map_style = 'default';
|
||||
|
||||
// Интересные места;
|
||||
// const places_layer;
|
||||
|
||||
export const map = L.map('map', {
|
||||
editable: true,
|
||||
layers: [ points, point_array.points, point_array.vectors, stickers.layers ]
|
||||
}).setView([55.0153275, 82.9071235], 13);
|
||||
|
||||
map.editTools.skipMiddleMarkers = true;
|
||||
|
||||
// Слой с интересными местами
|
||||
// const places_layer = L.markerClusterGroup({maxClusterRadius: 20});
|
||||
|
||||
// const poly = preparePoly(map); // начинаем новую полилинию
|
||||
|
||||
// const updateOverlays = () => updateMarks({ map, poly, km_marks });
|
||||
const updateOverlays = e => console.log();
|
||||
|
||||
const prepareMapLayer = provider => {
|
||||
L.tileLayer(provider, {
|
||||
attribution: 'Независимое Велосообщество',
|
||||
maxNativeZoom: 18,
|
||||
maxZoom: 18,
|
||||
//minZoom: 11
|
||||
}).addTo(map);
|
||||
};
|
||||
|
||||
const bindMapEvents = () => {
|
||||
|
||||
// при масштабировании карты масштабировать стрелки
|
||||
// map.on('zoom', function (e) {
|
||||
// $('.arr_mark > div').css('transform', 'scale(' + (map.getZoom()/13) + ')');
|
||||
// });
|
||||
|
||||
map.on('click', updateOverlays);
|
||||
};
|
||||
|
||||
export const setMode = variant => {
|
||||
mode = variant;
|
||||
};
|
||||
|
||||
// prepareMap();
|
||||
|
||||
export const prepareMap = () => {
|
||||
// Эта функция создаёт саму карту и наносит на неё маршруты в самом начале работы
|
||||
// создаём объект с картой
|
||||
map.doubleClickZoom.disable();
|
||||
prepareMapLayer(mapStyles[current_map_style]);
|
||||
|
||||
bindMapEvents();
|
||||
// bindPolyEvents({ poly, map, updateOverlays, clearKmMarks });
|
||||
};
|
228
src/parts/poly.js
Normal file
228
src/parts/poly.js
Normal file
|
@ -0,0 +1,228 @@
|
|||
import L from "leaflet";
|
||||
import { map } from "$utils/map";
|
||||
import { findDistance, middle_latlng } from "../js/common";
|
||||
|
||||
let poly = null;
|
||||
export const km_marks = L.layerGroup();
|
||||
|
||||
// const updateOverlays = () => updateMarks({ map, poly, km_marks });
|
||||
|
||||
const getRouteArray = poly => poly.toGeoJSON().geometry.coordinates;
|
||||
|
||||
|
||||
export const writeReduxData = ({ e, updatePolyCoords }) => {
|
||||
const route = getRouteArray(poly);
|
||||
const latlngs = route.map(([lng, lat]) => ({lat, lng}));
|
||||
|
||||
updatePolyCoords({ latlngs });
|
||||
};
|
||||
|
||||
const endMarker = ({ end_latlng, length }) => L.marker(
|
||||
[end_latlng[1], end_latlng[0]],
|
||||
{
|
||||
icon: L.divIcon(
|
||||
{
|
||||
html: `${length} км`,
|
||||
className: 'end_mark'
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
const startMarker = ({ start_latlng, map }) => L.marker(
|
||||
[start_latlng[1], start_latlng[0]],
|
||||
{
|
||||
icon: L.divIcon({
|
||||
html: `<div style="transform: scale(${(map.getZoom() / 13)});"><div class="arr_start"></div></div>`,
|
||||
className: 'arr_mark'
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
export const updateMarks = () => {
|
||||
km_marks.clearLayers();
|
||||
const route = getRouteArray(poly);
|
||||
const latlngs = poly.getLatLngs();
|
||||
let start_latlng;
|
||||
let end_latlng;
|
||||
let i;
|
||||
let rotation;
|
||||
let middle;
|
||||
let distance;
|
||||
|
||||
if (route.length > 0) {
|
||||
start_latlng = route[0];
|
||||
end_latlng = route[route.length - 1];
|
||||
km_marks.addLayer(startMarker({ start_latlng, map }));
|
||||
if (route.length > 1) {
|
||||
const segs = L.GeometryUtil.accumulatedLengths(poly);
|
||||
const length = Math.round(segs[segs.length - 1] / 1000);
|
||||
// end mark
|
||||
km_marks.addLayer(endMarker({ end_latlng, length }));
|
||||
|
||||
//and also length to panel:
|
||||
// $('#text_route_length').text(length + 'км');
|
||||
|
||||
for (i = 1; i < latlngs.length; i += 1) {
|
||||
rotation = L.GeometryUtil.bearing(latlngs[i - 1], latlngs[i]);
|
||||
middle = middle_latlng(latlngs[i], latlngs[i - 1]);
|
||||
distance = findDistance(latlngs[i - 1].lat, latlngs[i - 1].lng, latlngs[i].lat, latlngs[i].lng);
|
||||
|
||||
if (distance > 1) {
|
||||
km_marks.addLayer(L.marker([middle.lat, middle.lng], { icon: L.divIcon({ html: '<div style="transform: scale(' + (map.getZoom() / 13) + ');"><img src="misc/arr.png" style="transform: translateX(-4px) translateY(-4px) rotate(' + (270 + rotation) + 'deg);"></div>', className: 'arr_mark' }) }));
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// $('#text_route_length').text('0 км');
|
||||
}
|
||||
}
|
||||
// updatePolyCoords({ latlngs: route });
|
||||
// local_store_data();
|
||||
};
|
||||
|
||||
const clearKmMarks = () => km_marks.clearLayers();
|
||||
|
||||
const insertVertex = ({ e, updatePolyCoords }) => {
|
||||
// Добавляет редактирующую ручку по щелчку
|
||||
// если щелчок по кривой, а не по ручке И если ломаная в режиме редактирования. Иначе - перейти к редактированию
|
||||
if (e.originalEvent.target.tagName === 'path' && poly.editor._enabled) {
|
||||
// если щелкнуть по кривой во время редактирования, editable не должно рисовать новую точку
|
||||
if (e.type === 'editable:drawing:click') e.cancel();
|
||||
|
||||
let latlngs = poly.getLatLngs(); // набор точек ломанной
|
||||
let best = 10000;
|
||||
let pos = []; // переменные для определения принадлежности точки отрезку на ломанной
|
||||
|
||||
for(let i=0; i<latlngs.length-1; i++) {
|
||||
// Дальше определяем, лежит ли точка на отрезке ломаной перебором этих отрезков
|
||||
const x = e.latlng['lat'];
|
||||
const x1 = latlngs[i]['lat'];
|
||||
const x2 = latlngs[i+1]['lat'];
|
||||
const y = e.latlng['lng'];
|
||||
const y1 = latlngs[i]['lng'];
|
||||
const y2 = latlngs[i+1]['lng'];
|
||||
|
||||
// эта странная конструкция определяет, лежит ли вообще точка между двумя соседями на отрезке
|
||||
if ((
|
||||
(x1<x2 && (x>x1 && x<x2))
|
||||
||
|
||||
(x1>x2 && (x<x1 && x>x2))
|
||||
||
|
||||
(x1 === x2 && Math.abs(x-x1)>0.001)
|
||||
) && (
|
||||
(y1<y2 && (y>y1 && y<y2))
|
||||
||
|
||||
(y1>y2 && (y<y1 && y>y2))
|
||||
||
|
||||
(y1 === y2 && Math.abs(y-y1)>0.001)
|
||||
)
|
||||
) {
|
||||
// если да, то проверяем, далеко ли точка от самого отрезка между двумя точками
|
||||
let dx1 = x2 - x1;
|
||||
let dy1 = y2 - y1;
|
||||
let dx = x - x1;
|
||||
let dy = y - y1;
|
||||
let result = Math.abs((dx1 * dy) - (dx * dy1));
|
||||
if (result < best) {
|
||||
// это - не очень-то точная функция. Но по клику она определяет, по какому отрезку мы кликнули
|
||||
best = result;
|
||||
pos = [i, i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
// если точка найдена, добавляем её в отрезок
|
||||
if (pos.length>1) {
|
||||
poly.editor.disable();
|
||||
latlngs.splice(pos[1],0,e.latlng);
|
||||
poly.setLatLngs(latlngs);
|
||||
poly.editor.initVertexMarkers();
|
||||
poly.editor.enable();
|
||||
poly.editor.continueForward();
|
||||
|
||||
writeReduxData({ e, updatePolyCoords });
|
||||
}
|
||||
} else {
|
||||
// Рисование! Очистим буфер отмен :-)
|
||||
// redoBuffer = [];
|
||||
// если ломаная не в режиме редактирования или если мы, всё-таки, кликнули по ручке, просто активируем редактор
|
||||
// route_state('active');
|
||||
}
|
||||
};
|
||||
|
||||
export const bindPolyEvents = ({ updatePolyCoords }) => {
|
||||
// Если на карте что-то меняется, пересчитать километражи
|
||||
map.editTools.addEventListener('editable:drawing:mouseup', updateMarks);
|
||||
map.editTools.addEventListener('editable:vertex:dragend', updateMarks);
|
||||
|
||||
map.editTools.addEventListener('editable:vertex:dragend', e => writeReduxData({ e, updatePolyCoords }));
|
||||
map.editTools.addEventListener('editable:vertex:new', e => writeReduxData({ e, updatePolyCoords }));
|
||||
map.editTools.addEventListener('editable:vertex:deleted', e => writeReduxData({ e, updatePolyCoords }));
|
||||
|
||||
// Продолжить рисование после удаления точки
|
||||
map.editTools.addEventListener('editable:vertex:deleted', e => {
|
||||
poly.editor.continueForward();
|
||||
updateMarks();
|
||||
});
|
||||
|
||||
// Добавлять точек в полилинию по щелчку
|
||||
map.editTools.addEventListener('editable:drawing:click', e => insertVertex({ e, updatePolyCoords }));
|
||||
map.editTools.addEventListener('editable:drawing:clicked', () => updateMarks({ updatePolyCoords }));
|
||||
|
||||
// Это для точек. При перетаскивании конца указателя тащим точку
|
||||
// map.editTools.addEventListener('editable:vertex:drag', on_vertex_drag);
|
||||
|
||||
// при перетаскивании ручек убирать все отметки километров
|
||||
map.editTools.addEventListener('editable:vertex:dragstart', clearKmMarks);
|
||||
};
|
||||
|
||||
export const updatePoly = (latlngs) => {
|
||||
// const route = latlngs.map(([lat, lng]) => new L.latLng(lat, lng));
|
||||
if (!latlngs || latlngs.length < 2) return;
|
||||
|
||||
poly.setLatLngs(createLatLngs(latlngs));
|
||||
poly.addTo(map);
|
||||
poly.setStyle({ color: '#ff3333', weight: '5' });
|
||||
poly.editor.options.skipMiddleMarkers = true;
|
||||
poly.editor.disable().enable();
|
||||
poly.editor.continueForward();
|
||||
//
|
||||
};
|
||||
|
||||
export const createLatLngs = latlngs => latlngs.map(({ lat, lng }) => new L.LatLng(lat, lng));
|
||||
|
||||
const createPoly = () => {
|
||||
const result = map.editTools.startPolyline();
|
||||
|
||||
result.editor.enable();
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const restorePoly = latlngs => {
|
||||
const result = L.polyline(createLatLngs(latlngs), {color: 'red'}).addTo(map);
|
||||
|
||||
result.enableEdit().continueForward();
|
||||
result.editor.options.skipMiddleMarkers = true;
|
||||
|
||||
result.editor.reset();
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const preparePoly = ({ updatePolyCoords, latlngs }) => {
|
||||
map.addLayer(km_marks);
|
||||
|
||||
poly = (latlngs && latlngs.length)
|
||||
? restorePoly(latlngs)
|
||||
: createPoly();
|
||||
|
||||
updateMarks();
|
||||
|
||||
poly.setStyle({ color: '#ff3333', weight: '5' });
|
||||
|
||||
bindPolyEvents({ updatePolyCoords });
|
||||
|
||||
return poly;
|
||||
};
|
||||
|
124
webpack.config.js
Normal file
124
webpack.config.js
Normal file
|
@ -0,0 +1,124 @@
|
|||
// import webpack from 'webpack';
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebPackPlugin = require('html-webpack-plugin');
|
||||
// const FlowWebpackPlugin = require('flow-webpack-plugin');
|
||||
const { version } = require('./package.json');
|
||||
|
||||
const WebpackGitHash = require('webpack-git-hash');
|
||||
const { join } = require('path');
|
||||
|
||||
|
||||
/* Plugins */
|
||||
|
||||
const htmlPlugin = new HtmlWebPackPlugin({
|
||||
template: './src/index.html',
|
||||
filename: './index.html',
|
||||
title: 'Ether Corners',
|
||||
hash: false,
|
||||
});
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
const devtool = isDevelopment ? 'cheap-module-eval-source-map' : 'source-map';
|
||||
|
||||
// const flowPlugin = new FlowWebpackPlugin();
|
||||
|
||||
const gitPlugin = new WebpackGitHash();
|
||||
|
||||
|
||||
/* Resolve */
|
||||
|
||||
const resolve = {
|
||||
alias: {
|
||||
$components: join(__dirname, 'src/components'),
|
||||
$containers: join(__dirname, 'src/containers'),
|
||||
$constants: join(__dirname, 'src/constants'),
|
||||
$sprites: join(__dirname, 'src/sprites'),
|
||||
$config: join(__dirname, 'src/config'),
|
||||
$styles: join(__dirname, 'src/styles'),
|
||||
$redux: join(__dirname, 'src/redux'),
|
||||
$utils: join(__dirname, 'src/utils'),
|
||||
},
|
||||
|
||||
extensions: ['*', '.js', '.jsx', '.json']
|
||||
};
|
||||
|
||||
/* Configuration */
|
||||
|
||||
module.exports = () => {
|
||||
/* Export */
|
||||
const plugins = [
|
||||
htmlPlugin,
|
||||
// flowPlugin,
|
||||
gitPlugin,
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
|
||||
];
|
||||
|
||||
return {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader' }
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(eot|ttf|woff|woff2|otf)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]',
|
||||
outputPath: 'fonts/'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(png)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
options: {}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
devtool,
|
||||
resolve,
|
||||
plugins,
|
||||
entry: {
|
||||
// loader: './src/loader.js',
|
||||
app: './src/index.js',
|
||||
},
|
||||
output: {
|
||||
filename: '[name].bundle.[githash].js',
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
commons: {
|
||||
name: 'commons',
|
||||
chunks: 'initial',
|
||||
minChunks: 2,
|
||||
minSize: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
occurrenceOrder: true // To keep filename consistent between different modes (for example building only)
|
||||
},
|
||||
devServer: {
|
||||
historyApiFallback: true,
|
||||
port: 8000,
|
||||
contentBase: 'dist',
|
||||
publicPath: '/',
|
||||
hot: true,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue