Webpack - UglifyJsPlugin - dead code removing by switch

Ako ovo radis da bi radio debug, onda ti to ne treba. JS mozes debugirati kroz browser i vidjeti sto se dogadja.

Pa primjena istog je svakom po želji … a zahtjev je taj koji je. Napraviti modularne sekcije funkcije koje će zavisiti od enviromenta i neće uzrokovati nikakav suvišan dependency u okolini u kojoj se neće koristiti.

A što se tiče primjene, samo nebo je granica.

Jedna od opcija primjene, ugradnja automatskog testiranja codea. Vidi ideju: Automatsko testiranje code-a …it work like a charm. :slight_smile:

zašto ti toliko smeta taj kode u produkciji?

inače ne znam puno oko webpack-a, ali predlažem da isprobaš TypeScript što prije, ukoliko puno radiš sa JavaScript-om pogotovo velike projekte. Ne bi ni mogao u više različitih primjera kompajlirati.
Koliko vidim tu imaš provjeru da li su uneseni parametri ili tako nešto ti se u TypeScriptu ne bi moglo dogoditi.

Pa ništa nije toliko o glavu …ali ako se razmišlja o većoj skalabilnosti, onda je poželjno ne sijati konstantno nekakve repove… …danas ne smetaju, sutra možda hoće. Volim u startu optimizirati što se može.

Radim typescript filozofiju u C# i iskreno ne dopadaju mi se previše. Neke stvari su tu odlične, ali neke su katastrofalne. (Neke bi mogle biti odlične, ali u izvedbi Microsofta su i dalje poprilično aljkavo napravljene … ali što je da je, napravili su tu lavovski posao, i prisutne mane su logično realno stanje.)

No mislim da si krivo izvukao zaključak iz linije if(Develop)checkInputs(a,b,c); …i ta linija je dana kao ogledni primjer da se pokaže da funkcionalnost može biti proširena u development modeu. …ne radi se tu samo o provjeri tipova podataka na ulazu. …iako će biti i toga. Npr. u NormJS-u (ukoliko ti je to ime poznato xd) će takve sekcije code-a provjeravati da li su input parametri dobro standarizirani prema normativu normJS-a. …a tu se opet ne radi o onakvoj definiciji parametara koji se mogu opisati sa typescript sinstaksom.

Nadalje, kada bi se to i moglo deklarirati sa typescriptom, nebi ni htio ograničiti takvu funkcionalnost samo na one koji koriste typescript.

Što se tiče ostalih proširenja funkcionalnosti, zaista je nebo granica. Glupo je pokušavati ograničavati potencijal budućnosti razvoja na ideje koje tebi ili meni mogu trenutno pasti na pamet? Zar ne?
Bolje je postaviti plodno tlo…pa samo promatrati što će sve iz njega niknuti… :wink:
Ideje i potreba za određenim implementacijama dođu sami sa vremenom…bitno je ne ograničiti se previše u startu, tako da se te ideje kasnije lakše apsorbiraju i realiziraju.

Definitivno. Slažem se potpuno. Moj odgovor samo teži tomu da treba biti obziran prema kodu koji se piše i da ne bih nikad ovakvu eliminaciju koda radio s alatima.

Apsolutno. Ja mislim da je tema odlična i poučna za sve.

Ovaj primjer je dobar, ima smisla za development mode. Ali u development modu ne bih išao dalje od pisanja logova.

Pogledaj ovo:

Ne razumijes o cemu prica, TS je jedna totalno druga stvar.
Ovdje se radi o tome da on zeli imati specificne stvari samo za Development build.

if (process.env.NODE_ENV === 'development') {
  console.log("you are running development build")
}

Nema potrebe da ovo bude ukljuceno u production build, jer povecava velicinu fajla pogotovo ako imas dosta ovakve logike - a svima je ultimativni cilj da ima sto manje resurse.

Ovaj pristup koristi dosta popularnih JS frameworka - tipa React i Vue ce ti dati odredjena upozorenja/hitnove samo dok si u development mode-u, kasnije kad se sve minificira i optimizira za production te stvari ce biti obrisane iz finalnog bundel-a.

Napisem duzi komentar kasnije, sad nemam vremena :smiley:

1 Like

Meni se baš pokazalo da kada sa alatima počmeš upravljati codom…da si puno fleksibilniji i moćniji. Odjenom možeš raditi globalne effkete, zahvate…i magije. Što je ručno …nemoguće. :wink:
Veće manipulacije nad codom u ručnom modu …najdalji doseg je valjda CTRL+F …pa replace po svim skriptama. A to je tek katastrofalan pristup. Em si jako jako ograničen što možeš tako napraviti …em možeš pokvariti svašta nešto nesvjesno.

Statičke analize i prekompajliranje code-a …su po meni vrata u “Alice i zemlja čudesa”. Jer tamo više jednostavno nema nikakvih ograničenja koji ti sintaksa samog jezika nameće sama po sebi. Ako si dovoljno hrabar i lud, možeš uvoditi i vlastitu sintaksu i kompajlirati je u nativni jezik…itd. itd. Jednostavno su mogućnosti endless! Ali treba biti oprezan da se ne odvoji čovjek od ostatka comunnity-a, tj. da i dalje bude uklopiv u isti. :wink:

Pa o tome i pričamo. Three shaking ili dead code removing su ista stvar.
Samo three shaking radim sa pluginom untuar webpacka. Iskreno, ne znam napamet dali webpack može sada to samostalno napraviti bez plugina …možda i može…nebitno mi je.
E sad, jesi li mi nešto konkretno htio poručiti iz toga linka …nebi znao kada si linkao cijelo poglavlje o three shakingu. :slight_smile: Al pročitao sam to prije par godina… i to mi je jedna od dražih opcija koje dolaze sa webpackom na prilično jednostavan način. Al i prije webpacka sam taj proces automatizirao pomoću Google API servisa. Closure se zvao API, ako se ne varam.
Google je naime išao puno dalje u mogućnostima minimizacije …ali je forsirao da se piše puno njegovih notacija i dodatne sintakse …i u načelu je puno toga pucalo da sam tada izgubio vjeru da se to može jednostavno i elegantno postići. Dok me uglifyJS baš ugodno iznenadio …radi to poprilično “effort-less”…samo nisam još siguran koliko je ratio minimizacije kvalitetan. :slight_smile:

Jep…ali vjerujem da je on vidio liniju

if(Develop)checkInputs(a,b,c);

…pa se uhvatio za nju. Pretpostavio je da checkInputs radi nešto što bi se postiglo sa typescriptom…pa je otišao u tom smjeru.

Zato ću opet ponoviti. Nije bitno koja će se funkcionalnost na ovaj način ugrađivati …što se toga tiče, nebo je granica. Cilj je omogućiti modularni dependency…i to je to. A na svakome je da to koristi kako on smatra da mu paše. Ili da ne koristi. :wink:

da u pravu si @bozoou zbog te funkcije me navelo na Typescript tip parametra, interface i slično.

zanima me sada da li tako nešto ima angular riješeno.

Nisam čuo za taj pristup još da netko piše testove u samoj funkciji, ali za štošta još nisam čuo. Zapravo je taj uglify kao neki compiler ako sam dobro skužio koji ne samo da sažima kod već ga može i promijeniti ako prepozna da se ne koristi. Jesi na kraju dobio rješenje od ekipe ili još nisi?

P.S. pratio sam Norm.js topic

Niti će se pisati. :slight_smile: Pogledaj bolje link, ako ti se da naravno. Koncept ideje je da funkcija sama registrira parametre na ulazima i dobivene outpute …te nakon nekog updejta je onda sposobna samostalno prepoznati ako je neka izmjena u codu promjenila mapu ulaza/izlaza. Znači funkcija je sposobna samostalno testirati sama sebe. :slight_smile: Ali o tome nije ova tema …to je samo jedna od primjena što bi mogle funkcije dodatnoga mogle raditi kada im radna okolina dopusti da to rade.

Pa svaka minimizacija je promjena codea. A dead code removing je proces kada kompajler prepozna da neki code nema šanse da se koristi, pa ga onda izbaci kod kompajliranja. Npr. sljedeći code se sigurno neće izvršavati, zašto bi ga onda zadržali nakon kompajliranja:

if(0){
	console.log("Now, this is just log...but here can be a lot of things!  Ne pitaj zašto. Zato jer možda netko ne želi obrisati ovaj blok codea u vjeri da će ga jednom opet trebati aktivirati.")
}

Nadalje, ne radi se samo tu samo o mrtvim blokovima kao iz gornjeg primjera. Što ako imaš library od recimo 500kb, a efektino iz tog libriray-a u svom projektu koristiš ravno dvije funkcije?
500kb nije baš neosjetno, što će ti cijeli library onda?
Dead code removing je tu jako praktičan, jer će prepoznati samo one sekvence code-a koje su ti potrebne iz tog povećeg libriry-a …te ćeš u konačnom bundlu imati samo ono što zaista i koristiš iz tog library-a. Vrlo korisno!

Pogotovo ako uzmeš u obzir da taj library ima neke svoje dependencye…pa ti dependency opet imaju svoje dependencye…itd.

Bez dead code removinga moraš to sve povući da stvar nebi pukla…a sa dead code removingom se to sve fino pročitsti i u konačnom produkcijskom filu završi samo ono što se u projektu zaista i koristi. :wink:

Vjerujem da će raditi ono što je @belmin dao. Samo da povučem svježu instalaciju UglifyJsPlugin-a. Ali taj projekt ide po rasporedu nakon 18.00 :smiley:

1 Like

Tu ti je primjer i postavke za webpack kako da eliminiraš kod koji se ne koristi. Znam da nije jednostavno i da mi je odgovor preopćenit, ali svejedno mislim da ćeš uspjet kad cijelu stranu pročitaš.

Ali ti želiš i nešto specifično za development, ja mislim da je najbliže onomu što ti tražiš ovo što je @belmin napisao. Imaš primjer u ovoj sekciji:

I općenito na toj cijeloj stranici ima kako da podesiš dev i prod konfiguraciju za webpack.

webpack nije šala :smiley:

Apsolutno. Daleko od toga da sam protiv alata u smislu da treba sve ručno raditi. Ali je tema otišla na široko. Samo sam htio reći da treba i poznavati kod koji se piše, i pisati ga tako da je tebi kao developeru jasno zašto neki dio neće biti u production buildu. Ja osobno mislim da sad s ovim odgovorima gore ćeš kroz webpack i uglifyjs dobit ono što si tražio. Volio bi da podijeliš konfiguraciju webpacka i primjer par modula kad završiš, mislim da će koristit svima

Takvu konfiguraciju i imam, zasebno dev i prod (i lako se doda nešto treće ako se poželi)…od tamo sam i gledao kako se postavlja setup kada sam se prvi puta baktao sa webpackom. :wink:

I three shaking je do sada radio…makar sam smatrao da radi, jer je vrlo nepraktično provjeriti u minimiziranom/shakeanom fileu što je odrezano a što nije.

Sada ga malo natjeravam u iznimke, a automatizirao sam kontrolu što je shekano što nije (jer drugačije je baš pain in the ass gledati što je maknuto što nije) …pa sam uočio da postoje situacije kada dead code remover zakaže. No poigrat ću se još sa time…vjerujem da će već savjeti u ovoj temi polučiti rezultate. :slight_smile:

1 Like

Ne znam da se tu nešto naročito može primjetiti što nema gore u dokumentaciji…ali evo mog setupa:

webpack.common.js

const webpack = require("webpack");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
var WebpackNotifierPlugin = require('webpack-notifier');

module.exports = {
	target: "web",

	module: {
		rules: [
			// All files with a ".ts" or ".tsx" extension will be handled by "awesome-typescript-loader".
			{ test: /\.ts$/, loader: "awesome-typescript-loader" },
			{ test: /\.js$/, loader: 'bozoou_js2loader' },

			// All image files will be handled here
			{
				test: /\.(png|svg|jpg|gif)$/,
				use: [
					"file-loader"
				]
			},


			// All font files will be handled here
			{
				test: /\.(woff|woff2|eot|ttf|otf)$/,
				use: [
					{
						loader: "file-loader"
					}
				]
			},

			// All files with ".html" will be handled 
			{ test: /\.html$/, loader: "html-loader" },

			// All output ".js" files will have any sourcemaps re-processed by "source-map-loader".
			{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
		]
	},

	plugins: ([


		new WebpackNotifierPlugin({alwaysNotify:true}),

		// make sure we allow any jquery usages outside of our webpack modules
		// uz ovo dodaj u top entry point filea: $ = window.$;
		new webpack.ProvidePlugin({
			$: "jquery",
			jQuery: "jquery",
			"window.jQuery": "jquery"
		}),


		// Clean dist folder.
		new CleanWebpackPlugin(["./dist"], {
			"verbose": true // Write logs to console.
		}),

		// avoid publishing when compilation failed.
		new webpack.NoEmitOnErrorsPlugin(),

		new HtmlWebpackPlugin({
			inject: "body",
			filename: "../views/layout.html",
			template: "./views/layout_Template.php",
			showErrors:true
		})


	]),

	// pretty terminal output
	stats: { colors: true }
};

webpack.dev.js

const path = require("path");
const webpack = require("webpack");
const Merge = require("webpack-merge");
const CommonConfig = require("./webpack.common.js");

module.exports = Merge(CommonConfig, {
    devtool: "cheap-eval-source-map",
    entry: path.resolve(__dirname, "js/index.js"),
    output: {
        filename: "output.[hash].bundle.js",
        path: __dirname + "/dist",
        // Making sure the CSS and JS files that are split out do not break the template cshtml.
        publicPath: "./dist/",
        // Defining a global var that can used to call functions from within ASP.NET Razor pages.
        library: "aspAndWebpack",
        libraryTarget: "var"
    },
    resolve: {
        // Add ".ts" and ".tsx" as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json", ".html"],
        alias: {
          ROOT: path.resolve(__dirname, "./js/"),
          CROSS: 'D:/Programiranje/RESOURCE/NPM-CROSS/node_modules',    //individual per project
          NODE_CONFIG: path.resolve(__dirname, "./node_config/"),

        }
    },

    module: {
        rules: [
            // All css files will be handled here
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },

            // All files with ".less" will be handled and transpiled to css
            {
                test: /\.less$/,
                use: ["style-loader", "css-loader", "less-loader"]
			},
			// All files with ".scss" will be handled and transpiled to css
			{
				test: /\.scss/,
				use: ["style-loader", "css-loader", "sass-loader"]
			}
        ]
    },

	plugins: ([
        new webpack.DefinePlugin({
            "process.env": {
                "NODE_ENV": JSON.stringify("development")
            }
        })
    ]),
})

webpack.prod.js

const path = require("path");
const webpack = require("webpack");
const Merge = require("webpack-merge");
const CommonConfig = require("./webpack.common.js");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const extractLess = new ExtractTextPlugin({
    filename: "[name].[contenthash].css"
});

module.exports = Merge(CommonConfig, {
    devtool: "hidden-source-map",

    entry: {
        index: path.resolve(__dirname, 'js/index.js'),
        vendor: [
            "jquery",
            "jquery-validation",
            "bootstrap",
            "jquery-validation-unobtrusive"
        ]
    },

    output: {
        filename: "[name].[chunkhash].js",
        path: __dirname + "/dist",
        // Making sure the CSS and JS files that are split out do not break the template cshtml.
        publicPath: "./dist/",
        // Defining a global var that can used to call functions from within ASP.NET Razor pages.
        library: "aspAndWebpack",
        libraryTarget: "var"
    },
    resolve: {
        // Add ".ts" and ".tsx" as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json", ".html"],
        alias: {
            ROOT: path.resolve(__dirname, "./js/"),
            CROSS: 'D:/Programiranje/RESOURCE/NPM-CROSS/node_modules',    //individual per project
            NODE_CONFIG: path.resolve(__dirname, "./node_config/"),
        }
    },

    module: {
        rules: [          
            // All css files will be handled here
            {
                test: /\.css$/,
                use: extractLess.extract({ fallback: "style-loader", use: ["css-loader"] })
            },

            // All files with ".less" will be handled and transpiled to css
            {
                test: /\.less$/,
                use: extractLess.extract({
                    use: [{
                        loader: "css-loader", options: {
                            sourceMap: true
                        }
                    }, {
                        loader: "less-loader", options: {
                            sourceMap: true
                        }
                    }]
                })
			},
			// All files with ".scss" will be handled and transpiled to css
			{
				test: /\.scss/,
				use: ["style-loader", "css-loader", "sass-loader"]
			}
        ]
    },

    plugins: [
        new webpack.DefinePlugin({
            "process.env": {
                "NODE_ENV": JSON.stringify("production")
            }
        }),

        // Split out library into seperate bundle and remove from app bundle.
        new webpack.HashedModuleIdsPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
            name: "vendor"
        }),

        // Webpack boilerplate and manifest in seperate file.
        new webpack.optimize.CommonsChunkPlugin({
            name: "runtime"
        }),

        // Write out CSS bundle to its own file:
        extractLess,

        new webpack.LoaderOptionsPlugin({
            minimize: true,
            debug: false
		}),


        new webpack.optimize.UglifyJsPlugin({
            beautify: false,
            mangle: {
                screw_ie8: true,
                keep_fnames: true
            },
            compress: {
                screw_ie8: true,
                toplevel:true
            },
            comments: false
        })


        
    ]
})

Dev i Prod djele neke zajedničke segmente…moglo se više toga povezati preko common konfiguracije…ali nije strašno.

Od onog što se može primjetiti da sam tu dodao na “svoju ruku” je npr. bozoou_js2loader , to je moj prekompajler javascripta, (zasad) ne radi nešto naročito…ali par meni korisnih sitnica. Webpack mi je recimo zanimljiv upravo po tome što se jednostavno mogu ugraditi customizirani loaderi za određene tipove file-ova.

Nadalje, nešto što nisam u startu znao elegantno rješiti…to su sada ovi aliasovi. Tako imam alias za CROSS i NODE_CONFIG i to su mi čisto fine rješenja za sljedeće…

Dosta NPM komponenti si sam pravim i onda mi se pokazalo 101% nepraktičnim neku komponentu razvijati u njenoj source okolini…pa je od tamo uploadti u NPM repository…pa iz tog repozitorija instalirati updejtove u projekt. Znači ako trebaš neku sitnicu promjeniti na nekoj komponenti…to je ubij Bože vremena napraviti taj krug. A opet razvijat komponentu lokalno unutar projekta…je teški kaos za sve držati sinkroniziranim, pošto se iste komponente koriste uvijek na više projekata.

Tako sam si složio CROSS folder gdje mi čuče takve komponente koje reuse-am između projekata i onda ih tamo razvijam…a svi projekti se lokalno spajaju na taj CROSS folder. Naravno, ako kod importa komponente se to zada na način:

import {...} from "CROSS/component_name"

…onda je komponenta povučena iz CROSS foldera. A u konfiguraciji webpacka se mogu onda igrati koji je pravi source komponenti, tj. na koji folder će targetirati taj CROSS alias.
Time je razvoj drastično ubrzan…ali treba imati na umu da taj razvoj uvijek mora biti backward kompatibilan, pošto će svaka promjena utjecati na sve projekte koji se spajaju na CROSS. (Zato su tu automatski testovi Bogom dani, koji mogu samostalno zaključiti ako je došlo do promjene koja više nije backward kompatibilna)

Nadalje, NODE_CONFIG mi je alias za folder gdje se se nalazi customizacijski dio svake komponente, gdje je ta customizacija individualna po projektu.

Tako svaka komponenta koja ima konfiguracijski dio unutar sebe poziva:

import {...} from "NODE_CONFIG/someCustomizationFile"

…a onaj tko koristi takvu komponentu, mora u webpacku osigurati da postoji alias NODE_CONFIG i mora kustomizacijski file te komponente kopirati u folder koji je targetiran sa aliasom NODE_CONFIG.

Ovo sve sa dead code removingom, neće značajno promjeniti izgled webpack konfiguracije, sem ću se morati malo poigrati sa postavkama UglifyJsPlugin plugina. A dalje ću u codeu imati flagove za konstante poput:

const Develop = true;

…te ću prije bildanja postaviti te flagove kako mi odgovaraju za bildanje…i pokrenuti bildanje. Dalje će već dead code remover sve buildati kako treba s obzirom kako su ti flagovi postavljeni.

Ono što bi bilo malo bolje (ali ne znam kako se slaže, ako se može), da se ti flagovi mogu držati unutar webpack konfiguracije. Tako da kada trigiram recimo bildanje produkcijske verzije:
npm run build:prod

…da automatski pokretanjem te radnje se promjeni stanje flagova. Na taj način bi mogao jednoznačno odrediti koja vrsta bildanja ima koje stanje flagova. I samo bildanje bi bilo mrvicu praktičnije za odraditi. (Ono, ne moraš kopati po codeu prije bildanja i mijenjati stanje varijablama…tj. konstantama, hehe. Nego samo u cmd kucaš naredbu za buildanje i sve se desi samo po sebi. Time se ne mora ništa pamtiti…ili ti raditi u više koraka. Smatram da jedna procedura uvijek treba biti jedna procedura. Time smo smanjili teret koji nosimo dalje sa sobom i smanjujemo podložnost pogreški. Čim se jedna procedura mora napraviti u više koraka …moglo je bolje. :slight_smile: )

P.S.
ovo nije neki ogledni primjer webpack konfiguracije. :slight_smile:
Ja sam to poprilično na eks posložio prema uputama iz dokumentacije, bilo mi je samo bitno da radi, jer sam imao veliki time limit. …a ima tu svašta nešto čime se to može unaprijediti.
Nisam recimo uopće zašao u chunk-ove …a o njima treba razmisliti da se to poveže da svaki page učitava svoj bundle file. Nisam to još radio, mada smatram to praktički esencijalnim.
Jer ovako imamo jedan bundle file za cijeli projekt bez obzira što pageA i pageB trebaju možda sasvim druge skripte za izvršavanje svoje funkcionalnosti.
Za projekt koji ima par podstranica, to nije problem …ali ako ćemo o skalabilnosti i većem broju podstranica, onda treba razmisliti o tome da svaka stranica učitava samo ono što je njoj potrebno. To @belmin garant zna kako se radi. :slight_smile:

Nadalje, treba proučiti kako sa webpackom asinkrono dohvaćat bundlove/module …pa se određene komponente mogu pozivati u igru tek kada zatrebaju…

1 Like

Hmm. …sada sam tek probao live kako to radi i bojim se da ipak ne radi.
Ovo što je tebi ispalo /** no output */ to znači da si napisao funkciju koju nigdje nisi pozvao…pa nemaš nikakav code output. Logično, jer je sve dead code.

Išao sam sa sljedećim code-om:

const y=1;
function testFunkc(){
    //const y=1;
    if(y)return "YYY";

    console.log("XXX");

}
alert(testFunkc());

alert na dnu je ono što će diktirati kompajleru da funkcija sama po sebi nije dead code…tj. da se negdje koristi.

I sada očekujemo da ako se ispravno makne dead code, da nigdje nebi smjeli vidjeti “XXX”.
No ukoliko ostavim const y definiran izvan funkcije, “XXX” neće biti uklonjen.
A ukoliko const y deklariram unutar funkcije, onda će rezultat biti po očekivanom, štoviše, cijeli code će biti simpatično miniziran u: alert("YYY");

No i dalje me muči kako to da ne kuži da je konstanta deklarirana izvan scopea funkcije. Hmm…
…ako ga netko dobije da se ponaša kako treba, molit ću da kopira ovdje settings UglifyJS-a. :wink:

Nisam ni sumnj’o da ćeš uraditi nepravilno.
Evo kako se to standardizovano radi na standardizovan način (5 sekundi guglanja):

tj.

https://docs.npmjs.com/cli/link

Ostatak citata se zove verzioniranje paketa (lično smatram da si tek od toga eonima daleko trenutno pokazanim znanjem).

Uvijek bilo za nekog ko nema blage veze sa onim što radi a što je još gore ne želi ni da [pravilno] nauči.

I upravo sam iskopao rješenje. https://github.com/mishoo/UglifyJS2#conditional-compilation :slight_smile:
Točno ono što se traži su predvidjeli od strane uglifyJS-a … mogjuće da će ići i kroz konfiguraciju webpacka. :slight_smile:

Instaliranje lokalnog modula i dalje nije rješenje kojem sam težio. Opet moram nakon updejta lokalnog modula, raditi i update instalacije na projektu koji koristi taj lokalni modul. Ako imaš komponentu koju razvijaš paralelno sa projektom. (A to je gotovo uvijek slučaj kada si kreirao neku novu komponentu…pa je razvijaš uz projekt) …onda je to 101% nepraktično konstatno updejtati npm instalaciju nad projektom…zato jer svako malo nešto dodaješ u komponentu.

Što se tiče verzioniranja, tu si skoro u pravu. Mojim pristupom nema verzioniranja dok si u razvoju. Ili ipak ima? Ima, jer ipak preko package.jsona možeš projekt zaključati na željenu verziju neke komponente koja se nalazi u npm repositoriju. (Može biti i u lokalnom, prema ovom tvom linku). I onda kada bi projekt htio povezati sa verzijama koje su deklarirane u package.json-u, samo bi trebao alias CROSS iz tog projekta povezati sa folderom node_modules koji se nalazi u instalaciji tog projekta …i sve bi se odspojilo sa globalnog CROSS direktorija i radilo kao i inače.
Jedino da bi to radilo, povremeno ipak treba lokalne komponente publishati u NPM repositorij pod određenim verzijama. Al to treba napraviti samo za situaciju kada se ide sa nečim što nije backward kompatibilno. (Ili ako sheramo updejt komponete sa nekim tko je remote)

Ali kako backward ne-kompatibilan code nosi malo više problema sa sobom…ja izbjegavam oslanjanje na verzioniranje u potpunosti. Radije se striktno držim da sve mora biti backward kompatibilno i rezove u tom smislu radim planski kada se od nečega jednostavno mora odustati. I takve rezove odgađam koliko je max moguće, tako da kada dođe do njih da se presloži sve što se prethodnih godina planiralo presložiti.

I tada opet ne pribjegavam verzioniranju, nego novi modul nastavljam razvijati pod novim imenom.

Znači za mene je backward compability zlato… i unatoč nekim lošim programskim rješenjima koji se uglave putem, dajem prednost backward compabilityu, a ne “velikom potopu” i trganju prošlosti.

P.S.
i na kraju Bože moj, nitko nije savršen…nit smatram da je moje rješenje neko extra. Ali za moje potrebe je više nego zadovoljavajuće…dok god mi je radni flow lagan i neometan, smatram rješenje dobrim. Kada nešto zašteka, tražit ću kako to unaprijediti. :wink:

Izgleda da ćeš trebati u webpacku u postavaka uglifyjs pod compress dodat ovaj objekt:

    global_defs: {
        DEBUG: false
    }
1 Like

^^

Pojmovi za tebe da guglaš (i naučiš kako se radi): [“git”, “release”, “tag”].