ป้องกัน RequireJS จากการแคชสคริปต์ที่จำเป็น


302

RequireJS ดูเหมือนว่าจะทำอะไรบางอย่างภายในว่าแคชจำเป็นต้องใช้ไฟล์จาวาสคริปต์ หากฉันทำการเปลี่ยนแปลงหนึ่งในไฟล์ที่ต้องการฉันจะต้องเปลี่ยนชื่อไฟล์เพื่อให้การเปลี่ยนแปลงมีผล

เคล็ดลับทั่วไปของการต่อท้ายหมายเลขรุ่นเป็นพารามิเตอร์การสอบถามถึงจุดสิ้นสุดของชื่อไฟล์ไม่สามารถทำงานกับ requirejs <script src="jsfile.js?v2"></script>

สิ่งที่ฉันกำลังมองหาคือวิธีป้องกันการแคชภายในสคริปต์ที่ต้องการของ RequireJS โดยไม่ต้องเปลี่ยนชื่อไฟล์สคริปต์ของฉันทุกครั้งที่มีการอัปเดต

โซลูชันข้ามแพลตฟอร์ม:

ตอนนี้ฉันกำลังใช้urlArgs: "bust=" + (new Date()).getTime()สำหรับแคชอัตโนมัติในระหว่างการพัฒนาและurlArgs: "bust=v2"สำหรับการผลิตที่ฉันเพิ่มเวอร์ชันที่มีรหัสฮาร์ดโค้ดหลังจากเผยแพร่สคริปต์ที่ต้องการที่อัปเดตแล้ว

บันทึก:

@Dustin Getz พูดถึงในคำตอบล่าสุดว่าเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome จะวางจุดพักระหว่างการดีบักเมื่อไฟล์ Javascript มีการรีเฟรชอย่างต่อเนื่องเช่นนี้ วิธีแก้ปัญหาหนึ่งคือการเขียนdebugger;โค้ดเพื่อทริกเกอร์เบรกพอยต์ในตัวแก้ไขข้อบกพร่องจาวาสคริปต์ส่วนใหญ่

โซลูชันเฉพาะเซิร์ฟเวอร์:

สำหรับวิธีแก้ปัญหาเฉพาะที่อาจทำงานได้ดีขึ้นสำหรับสภาพแวดล้อมเซิร์ฟเวอร์ของคุณเช่น Node หรือ Apache ดูคำตอบด้านล่าง


คุณแน่ใจหรือว่านี่ไม่ใช่เซิร์ฟเวอร์หรือไคลเอนต์ที่ทำการแคชอยู่ใช่ไหม (ใช้ js ที่ต้องการมาสองสามเดือนแล้วและไม่ได้สังเกตอะไรที่คล้ายกัน) IE ถูกจับการแคชผลการดำเนินการ MVC โครเมี่ยมกำลังแคชแม่แบบ html ของเรา แต่ไฟล์ js ดูเหมือนจะรีเฟรชเมื่อแคชของเบราว์เซอร์ถูกรีเซ็ต ฉันคิดว่าถ้าคุณต้องการใช้ประโยชน์จากการแคช แต่คุณไม่สามารถทำตามปกติได้เพราะคำขอจาก js ที่ต้องการนั้นถูกลบสตริงการสืบค้นที่อาจทำให้เกิดปัญหาหรือไม่
PJUK

ฉันไม่แน่ใจว่า RequireJS จะลบตัวเลขที่ต่อท้ายแบบนั้นหรือไม่ มันอาจจะเป็นเซิร์ฟเวอร์ของฉัน น่าสนใจว่า RequireJS มีการตั้งค่าแคชบัสเตอร์อย่างไรดังนั้นคุณอาจถูกต้องเกี่ยวกับการลบตัวเลขที่ต่อท้ายของฉันในไฟล์ที่ต้องการ
BumbleB2na

ฉันปรับปรุงคำตอบของฉันกับวิธีการแก้ปัญหาที่อาจเกิดขึ้นแคช
ดัสตินเก็ตซ์

ตอนนี้ฉันสามารถเพิ่มสิ่งต่อไปนี้ในบทกวี ที่ฉันโพสต์ไว้ในบล็อกโพสต์ของฉันเมื่อเช้านี้: codrspace.com/dexygen/และนั่นคือไม่เพียง แต่ฉันต้องเพิ่มการป้องกันแคช แต่ต้องไม่สนใจการรีเฟรช
Dexygen

ฉันสับสนเกี่ยวกับกรณีการใช้งานสำหรับสิ่งนี้ .... นี่เป็นโมดูลสำหรับการโหลดใหม่ของ AMD ในส่วนหน้าหรืออะไร
Alexander Mills

คำตอบ:


457

RequireJS สามารถกำหนดค่าให้ต่อท้ายค่ากับแต่ละ URL ของสคริปต์สำหรับการใช้แคช

จากเอกสาร RequireJS ( http://requirejs.org/docs/api.html#config ):

urlArgs : อาร์กิวเมนต์สตริงข้อความค้นหาพิเศษผนวกเข้ากับ URL ที่ RequireJS ใช้เพื่อดึงข้อมูลทรัพยากร มีประโยชน์มากที่สุดในการหยุดการแคชเมื่อเบราว์เซอร์หรือเซิร์ฟเวอร์ไม่ได้กำหนดค่าอย่างถูกต้อง

ตัวอย่างต่อท้าย "v2" กับสคริปต์ทั้งหมด:

require.config({
    urlArgs: "bust=v2"
});

เพื่อจุดประสงค์ในการพัฒนาคุณสามารถบังคับให้ RequireJS เลี่ยงผ่านแคชได้โดยการต่อเวลาประทับ:

require.config({
    urlArgs: "bust=" + (new Date()).getTime()
});

46
มีประโยชน์มากขอบคุณ ฉันกำลังใช้urlArgs: "bust=" + (new Date()).getTime()สำหรับแคชอัตโนมัติในระหว่างการพัฒนาและurlArgs: "bust=v2"การผลิตที่ฉันเพิ่ม NUM เวอร์ชันที่กำหนดรหัสแบบยากหลังจากเปิดตัวสคริปต์ที่จำเป็นต้องมีการอัปเดต
BumbleB2na

9
... เช่นเดียวกับเครื่องมือเพิ่มประสิทธิภาพการทำงานคุณสามารถใช้ Math.random () แทน (new Date ()). getTime () มันงามมากขึ้นไม่สร้างวัตถุและบิตเร็วขึ้นjsperf.com/speedcomparison
Vlad Tsepelev

2
คุณสามารถทำให้มันเล็กลงได้อีกนิด:urlArgs: "bust=" + (+new Date)
mrzmyr

11
ฉันคิดว่าการเก็บแคชทุกครั้งเป็นความคิดที่แย่มาก น่าเสียดายที่ RequireJS ไม่ได้เสนอทางเลือกอื่น เราใช้ urlArgs แต่อย่าใช้การสุ่มหรือการประทับเวลาสำหรับสิ่งนี้ แต่เราใช้ Git SHA ปัจจุบันของเราด้วยวิธีนี้จะเปลี่ยนเฉพาะเมื่อเราปรับใช้รหัสใหม่
Ivan Torres

5
ตัวแปร "v2" นี้ทำงานในการผลิตได้อย่างไรถ้าไฟล์ที่ให้สตริง "v2" นั้นถูกแคชไว้ด้วยตัวเอง? ถ้าฉันปล่อยโปรแกรมใหม่ในการผลิตเพิ่ม "v3" ไม่ได้ไปทำอะไรเป็นโปรแกรมที่ช่วยให้มีความสุขกับการทำงานกับไฟล์ v2 แคชรวมทั้งการตั้งค่าเก่ากับ urlArgsv2
Benny Bottema

54

อย่าใช้ urlArgs สำหรับสิ่งนี้!

ต้องการโหลดสคริปต์ที่เกี่ยวข้องกับส่วนหัวแคช http (สคริปต์โหลดเต็มไปด้วยการแทรกแบบไดนามิก<script>ซึ่งหมายความว่าคำขอมีลักษณะเหมือนกับการโหลดเนื้อหาเก่า ๆ )

แสดงเนื้อหาจาวาสคริปต์ของคุณด้วยส่วนหัว HTTP ที่เหมาะสมเพื่อปิดใช้งานการแคชระหว่างการพัฒนา

urlArgs ของการใช้ require หมายถึงเบรกพอยต์ใด ๆ ที่คุณตั้งค่าไว้จะไม่ถูกสงวนไว้ตลอดการรีเฟรช ท้ายที่สุดคุณจำเป็นต้องวางdebuggerคำสั่งทุกที่ในรหัสของคุณ ไม่ดี ฉันใช้urlArgsสำหรับสินทรัพย์ที่แคชในระหว่างการอัพเกรดการผลิตด้วย git sha; จากนั้นฉันสามารถกำหนดให้สินทรัพย์ของฉันถูกเก็บถาวรตลอดไปและรับประกันได้ว่าจะไม่มีสินทรัพย์เก่า

ในการพัฒนาผมเยาะเย้ยร้องขออาแจ็กซ์ทั้งหมดที่มีความซับซ้อนmockjaxกำหนดค่าแล้วฉันสามารถใช้ app ของฉันในโหมดจาวาสคริปต์เท่านั้นมี10 บรรทัดเซิร์ฟเวอร์หลามแคช http กับทุกปิด สิ่งนี้ทำให้ฉันมีขนาดใหญ่ขึ้นสำหรับแอปพลิเคชั่น "enterprisey" ที่มีจุดสิ้นสุดเว็บเซอร์ที่สงบนับร้อย เรายังมีนักออกแบบตามสัญญาที่สามารถทำงานกับฐานการผลิตจริงของเราโดยไม่ให้เขาเข้าถึงรหัสแบ็กเอนด์ของเรา


8
@ JamesP.Wright เพราะ (ใน Chrome เป็นอย่างน้อย) เมื่อคุณตั้งค่าเบรกพอยต์สำหรับบางสิ่งที่เกิดขึ้นเมื่อโหลดหน้าเว็บจากนั้นคลิกรีเฟรชจุดพักจะไม่กระทบเนื่องจาก URL มีการเปลี่ยนแปลงและ Chrome ได้เปลี่ยนจุดพัก ฉันชอบที่จะรู้วิธีแก้ปัญหาเฉพาะลูกค้านี้
Drew Noakes

1
ขอบคุณดัสติน หากคุณพบวิธีนี้กรุณาโพสต์ ในระหว่างนี้คุณสามารถใช้debugger;รหัสของคุณได้ทุกที่ที่คุณต้องการให้เบรกพอยต์ยังคงอยู่
BumbleB2na

2
สำหรับทุกคนที่ใช้ http-server บนโหนด (npm ติดตั้ง http-server) นอกจากนี้คุณยังสามารถปิดใช้งานการแคชด้วย -c-1 (เช่น http-server -c-1)
Yourpalal

5
คุณสามารถปิดใช้งานการแคชใน Chrome เพื่อแก้ไขปัญหาการดีบักระหว่างการพัฒนา: stackoverflow.com/questions/5690269/…
Deepak Joy

5
+1 ถึง !!! ไม่ใช้ urlArgs ในการผลิต !!! . ลองนึกภาพกรณีที่เว็บไซต์ของคุณมีไฟล์ 1,000 JS (ใช่เป็นไปได้!) และโหลดจะถูกควบคุมโดย requiredJS ตอนนี้คุณปล่อย v2 หรือเว็บไซต์ของคุณที่มีการเปลี่ยนแปลงไฟล์ JS เพียงไม่กี่! แต่ด้วยการเพิ่ม urlArgs = v2 คุณจำเป็นต้องโหลดไฟล์ JS ทั้งหมด 1,000 ไฟล์! คุณจะจ่ายการเข้าชมจำนวนมาก! เฉพาะไฟล์ที่ถูกแก้ไขเท่านั้นที่ควรจะโหลดใหม่ส่วนไฟล์อื่น ๆ ทั้งหมดควรตอบกลับด้วยสถานะ 304 (ไม่ได้รับการแก้ไข)
walv

24

วิธีแก้ปัญหา urlArgs มีปัญหา น่าเสียดายที่คุณไม่สามารถควบคุมพร็อกซีเซิร์ฟเวอร์ทั้งหมดที่อาจอยู่ระหว่างคุณกับเว็บเบราว์เซอร์ของผู้ใช้ ขออภัยพร็อกซีเซิร์ฟเวอร์เหล่านี้บางตัวสามารถกำหนดค่าให้ละเว้นพารามิเตอร์ URL เมื่อแคชไฟล์ หากสิ่งนี้เกิดขึ้นไฟล์ JS ของคุณเวอร์ชันผิดจะถูกส่งไปยังผู้ใช้ของคุณ

ในที่สุดฉันก็ยอมแพ้และนำการแก้ไขของฉันไปใช้กับ หากคุณยินดีแก้ไขไลบรารี requirejs เวอร์ชันของคุณโซลูชันนี้อาจใช้งานได้สำหรับคุณ

คุณสามารถดูแพทช์ได้ที่นี่:

https://github.com/jbcpollak/requirejs/commit/589ee0cdfe6f719cd761eee631ce68eee09a5a67

เมื่อเพิ่มแล้วคุณสามารถทำสิ่งนี้ในการกำหนดค่าของคุณ:

var require = {
    baseUrl: "/scripts/",
    cacheSuffix: ".buildNumber"
}

ใช้ระบบการสร้างหรือสภาพแวดล้อมเซิร์ฟเวอร์ของคุณเพื่อแทนที่buildNumberด้วยรหัสการแก้ไข / รุ่นซอฟต์แวร์ / สีที่ชื่นชอบ

การใช้ต้องมีดังนี้:

require(["myModule"], function() {
    // no-op;
});

จะทำให้ต้องมีการร้องขอไฟล์นี้:

http://yourserver.com/scripts/myModule.buildNumber.js

ในสภาพแวดล้อมเซิร์ฟเวอร์ของเราเราใช้กฎการเขียน url ใหม่เพื่อแยก buildNumber และให้บริการไฟล์ JS ที่ถูกต้อง วิธีนี้เราไม่ต้องกังวลกับการเปลี่ยนชื่อไฟล์ JS ทั้งหมดของเรา

แพตช์จะไม่สนใจสคริปต์ใด ๆ ที่ระบุโปรโตคอลและจะไม่มีผลกับไฟล์ที่ไม่ใช่ JS

สิ่งนี้ทำงานได้ดีสำหรับสภาพแวดล้อมของฉัน แต่ฉันรู้ว่าผู้ใช้บางคนอาจต้องการคำนำหน้ามากกว่าคำต่อท้ายมันควรจะง่ายต่อการปรับเปลี่ยนคอมมิทของฉันให้เหมาะกับความต้องการของคุณ

ปรับปรุง:

ในการสนทนาคำขอดึงผู้เขียน requirejs แนะนำสิ่งนี้อาจทำงานเป็นวิธีแก้ไขปัญหาหมายเลขนำหน้าการแก้ไข

var require = {
    baseUrl: "/scripts/buildNumber."
};

ฉันไม่ได้ลองสิ่งนี้ แต่ความหมายก็คือว่าจะขอ URL ต่อไปนี้:

http://yourserver.com/scripts/buildNumber.myModule.js

ซึ่งอาจทำงานได้ดีมากสำหรับคนจำนวนมากที่สามารถใช้ส่วนนำ

ต่อไปนี้เป็นคำถามที่ซ้ำกันที่เป็นไปได้:

ต้องการแคช JS และพร็อกซี

require.js - ฉันจะตั้งค่าเวอร์ชันในโมดูลที่ต้องการเป็นส่วนหนึ่งของ URL ได้อย่างไร


1
ฉันอยากเห็นการอัปเดตของคุณเข้ามาในการสร้าง requirejs อย่างเป็นทางการ ผู้เขียนหลักของ requirejs ก็อาจสนใจเช่นกัน (ดู @ คำตอบของ @ Louis ด้านบน)
BumbleB2na

@ BumbleB2na - อย่าลังเลที่จะแสดงความคิดเห็นใน PullRequest ( github.com/jrburke/requirejs/pull/1017 ) jrburke ดูเหมือนจะไม่สนใจ เขาแนะนำวิธีแก้ปัญหาโดยใช้คำนำหน้าชื่อไฟล์ฉันจะอัปเดตคำตอบของฉันเพื่อรวมไว้
JBCP

1
เป็นการปรับปรุงที่ดี ฉันคิดว่าฉันชอบข้อเสนอแนะนี้จากผู้เขียน แต่เป็นเพราะฉันใช้แบบแผนการตั้งชื่อนี้เมื่อไม่นานมานี้: /scripts/myLib/v1.1/. ฉันพยายามเพิ่ม postfix (หรือคำนำหน้า) ในชื่อไฟล์ของฉันอาจเป็นเพราะ jquery ทำ แต่หลังจากนั้นไม่นานฉัน [เกียจคร้านและ] เริ่มเพิ่มหมายเลขเวอร์ชันในโฟลเดอร์พาเรนต์ ฉันคิดว่ามันทำให้การบำรุงรักษาง่ายขึ้นสำหรับฉันในเว็บไซต์ขนาดใหญ่ แต่ตอนนี้คุณทำให้ฉันต้องกังวลเกี่ยวกับการเขียน URL ฝันร้าย
BumbleB2na

1
ระบบ Front Front สมัยใหม่เพียงแค่เขียนไฟล์ JS และด้วยผลรวม MD5 ในชื่อไฟล์จากนั้นเขียนไฟล์ HTML ใหม่เพื่อใช้ชื่อไฟล์ใหม่เมื่อสร้าง
JBCP

ใช้งานได้เมื่อฉันต้องการ js ภายในไฟล์ jspx หรือไม่เช่นนี้<script data-main="${pageContext.request.contextPath}/resources/scripts/main" src="${pageContext.request.contextPath}/resources/scripts/require.js"> <jsp:text/> </script> <script> require([ 'dev/module' ]); </script>
masT

19

ได้รับแรงบันดาลใจจากExpire cache บน require.js data-mainเราอัพเดตสคริปต์การปรับใช้ของเราด้วยภารกิจ ant ต่อไปนี้:

<target name="deployWebsite">
    <untar src="${temp.dir}/website.tar.gz" dest="${website.dir}" compression="gzip" />       
    <!-- fetch latest buildNumber from build agent -->
    <replace file="${website.dir}/js/main.js" token="@Revision@" value="${buildNumber}" />
</target>

จุดเริ่มต้นของ main.js มีลักษณะอย่างไร:

require.config({
    baseUrl: '/js',
    urlArgs: 'bust=@Revision@',
    ...
});

11

ในการผลิต

urlArgs อาจทำให้เกิดปัญหา!

ผู้เขียนหลักของ requirejs ไม่ต้องการใช้urlArgs :

สินทรัพย์ที่นำไปใช้ผมชอบที่จะนำรุ่นหรือแฮสำหรับการสร้างทั้งหมดเป็นสร้างไดเรกทอรีแล้วเพียงแค่ปรับเปลี่ยนbaseUrlการตั้งค่าที่ใช้สำหรับโครงการเพื่อการใช้งานที่ versioned baseUrlไดเรกทอรีเป็น จากนั้นจะไม่มีการเปลี่ยนแปลงไฟล์อื่น ๆ และจะช่วยหลีกเลี่ยงปัญหาพร็อกซีบางอย่างซึ่งอาจไม่ได้แคช URL ที่มีสตริงข้อความค้นหา

[เหมืองใส่สไตล์]

ฉันทำตามคำแนะนำนี้

ในการพัฒนา

ฉันชอบที่จะใช้เซิร์ฟเวอร์ที่เก็บไฟล์อย่างชาญฉลาดซึ่งอาจมีการเปลี่ยนแปลงบ่อยครั้ง: เซิร์ฟเวอร์ที่ปล่อยLast-ModifiedและตอบสนองIf-Modified-Sinceด้วย 304 เมื่อเหมาะสม แม้แต่เซิร์ฟเวอร์ที่อยู่บนพื้นฐานของการตั้งค่าด่วนของโหนดที่ให้บริการไฟล์แบบคงที่ก็สามารถทำได้ทันที มันไม่จำเป็นต้องทำอะไรกับเบราว์เซอร์ของฉันและไม่ทำให้เบรกพอยต์เสียหาย


คะแนนดี แต่คำตอบของคุณเฉพาะกับสภาพแวดล้อมเซิร์ฟเวอร์ของคุณ อาจเป็นทางเลือกที่ดีสำหรับใครก็ตามที่สะดุดนี้เป็นคำแนะนำเมื่อเร็ว ๆ นี้สำหรับการเพิ่มหมายเลขเวอร์ชันในชื่อไฟล์แทนที่จะเป็นพารามิเตอร์ตัวกรองสตริง นี่คือข้อมูลเพิ่มเติมเกี่ยวกับหัวเรื่องนั้น: stevesouders.com/blog/2008/08/23/…
BumbleB2na

เรากำลังประสบกับปัญหาเฉพาะนี้ในระบบการผลิต ฉันแนะนำให้แก้ไขชื่อไฟล์ของคุณแทนที่จะใช้พารามิเตอร์
JBCP

7

ฉันนำตัวอย่างนี้จากAskApacheและใส่ลงในไฟล์. conf แยกจากเว็บเซิร์ฟเวอร์ Apache ในเครื่อง (ในกรณีของฉัน /etc/apache2/others/preventcaching.conf):

<FilesMatch "\.(html|htm|js|css)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</FilesMatch>

สำหรับการพัฒนาสิ่งนี้ใช้ได้ดีโดยไม่จำเป็นต้องเปลี่ยนรหัส สำหรับการผลิตฉันอาจใช้วิธีของ @ dvtoever


6

แก้ไขด่วนสำหรับการพัฒนา

สำหรับการพัฒนาคุณสามารถปิดการใช้งานแคชใน Chrome Dev Tools ( ปิดใช้งานแคช Chrome สำหรับการพัฒนาเว็บไซต์ ) การปิดใช้งานแคชจะเกิดขึ้นเฉพาะเมื่อกล่องโต้ตอบเครื่องมือ dev เปิดอยู่ดังนั้นคุณไม่จำเป็นต้องกังวลเกี่ยวกับการสลับตัวเลือกนี้ทุกครั้งที่คุณเรียกดูเป็นประจำ

หมายเหตุ: การใช้ ' urlArgs ' เป็นโซลูชันที่เหมาะสมในการผลิตเพื่อให้ผู้ใช้ได้รับรหัสล่าสุด แต่มันทำให้การแก้จุดบกพร่องยากเพราะ Chrome ทำให้จุดพักหยุดใช้งานไม่ได้กับการรีเฟรชทุกครั้ง (เพราะเป็นไฟล์ 'ใหม่' ที่ให้บริการในแต่ละครั้ง)


3

ฉันไม่แนะนำให้ใช้ ' urlArgs ' สำหรับแคชที่เต็มไปด้วย RequireJS เช่นนี้ไม่สามารถแก้ปัญหาได้อย่างเต็มที่ การอัปเดตเวอร์ชันจะไม่ส่งผลให้ดาวน์โหลดทรัพยากรทั้งหมดแม้ว่าคุณจะเปลี่ยนทรัพยากรเพียงครั้งเดียวก็ตาม

เพื่อจัดการปัญหานี้ฉันแนะนำให้ใช้โมดูล Grunt เช่น 'filerev' สำหรับการสร้างหมายเลขการแก้ไข ด้านบนของนี้ฉันได้เขียนงานที่กำหนดเองใน Gruntfile เพื่อปรับปรุงการแก้ไขไม่จำเป็นต้องมีทุกที่

หากจำเป็นฉันสามารถแบ่งปันข้อมูลโค้ดสำหรับงานนี้


ฉันใช้การผสมผสานของ grunt-filerev และ grunt-cache-buster เพื่อเขียนไฟล์ Javascript ใหม่
Ian Jamieson

2

นี่คือวิธีที่ฉันทำใน Django / Flask (สามารถปรับให้เข้ากับระบบภาษา VCS อื่น ๆ ได้อย่างง่ายดาย):

ในของคุณconfig.py(ฉันใช้สิ่งนี้ใน python3 ดังนั้นคุณอาจต้องปรับแต่งการเข้ารหัสใน python2)

import subprocess
GIT_HASH = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8')

จากนั้นในเทมเพลตของคุณ:

{% if config.DEBUG %}
     require.config({urlArgs: "bust=" + (new Date().getTime())});
{% else %}
    require.config({urlArgs: "bust=" + {{ config.GIT_HASH|tojson }}});
{% endif %}
  • ไม่ต้องการกระบวนการสร้างด้วยตนเอง
  • ทำงานเพียงgit rev-parse HEADครั้งเดียวเมื่อแอปเริ่มต้นและเก็บไว้ในconfigวัตถุ

0

โซลูชันแบบไดนามิก (ไม่มี urlArgs)

มีวิธีแก้ไขปัญหาอย่างง่ายสำหรับปัญหานี้เพื่อให้คุณสามารถโหลดหมายเลขการแก้ไขเฉพาะสำหรับทุกโมดูลได้

คุณสามารถบันทึกฟังก์ชั่น requirejs.load ต้นฉบับเขียนทับมันด้วยฟังก์ชั่นของคุณเองและแยกวิเคราะห์ url ที่แก้ไขแล้วของคุณไปที่ requirejs.load ดั้งเดิมอีกครั้ง:

var load = requirejs.load;
requirejs.load = function (context, moduleId, url) {
    url += "?v=" + oRevision[moduleId];
    load(context, moduleId, url);
};

ในกระบวนการสร้างของเราฉันใช้ "gulp-rev" เพื่อสร้างไฟล์รายการที่มีการแก้ไขทั้งหมดของโมดูลทั้งหมดที่ใช้ beeing รุ่นที่ง่ายของงานอึกของฉัน:

gulp.task('gulp-revision', function() {
    var sManifestFileName = 'revision.js';

    return gulp.src(aGulpPaths)
        .pipe(rev())
        .pipe(rev.manifest(sManifestFileName, {
        transformer: {
            stringify: function(a) {
                var oAssetHashes = {};

                for(var k in a) {
                    var key = (k.substr(0, k.length - 3));

                    var sHash = a[k].substr(a[k].indexOf(".") - 10, 10);
                    oAssetHashes[key] = sHash;
                }

                return "define([], function() { return " + JSON.stringify(oAssetHashes) + "; });"
            }
        }
    }))
    .pipe(gulp.dest('./'));
});

สิ่งนี้จะสร้างโมดูล AMD ที่มีหมายเลขการแก้ไขไปยัง moduleNames ซึ่งรวมอยู่ใน 'oRevision' ใน main.js ซึ่งคุณเขียนทับฟังก์ชั่น requirejs.load ดังที่แสดงไว้ก่อนหน้านี้


-1

นี่คือนอกเหนือไปจากคำตอบที่ยอมรับของ @phil mccull

ฉันใช้วิธีการของเขา แต่ฉันก็ทำให้กระบวนการโดยอัตโนมัติด้วยการสร้างเทมเพลต T4 เพื่อให้ทำงานก่อนสร้าง

คำสั่งสร้างล่วงหน้า:

set textTemplatingPath="%CommonProgramFiles(x86)%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
if %textTemplatingPath%=="\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe" set textTemplatingPath="%CommonProgramFiles%\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\texttransform.exe"
%textTemplatingPath% "$(ProjectDir)CacheBuster.tt"

ป้อนคำอธิบายรูปภาพที่นี่

เทมเพลต T4:

ป้อนคำอธิบายรูปภาพที่นี่

ไฟล์ที่สร้าง: ป้อนคำอธิบายรูปภาพที่นี่

เก็บในตัวแปรก่อนที่จะต้องโหลดไฟล์ config: ป้อนคำอธิบายรูปภาพที่นี่

การอ้างอิงใน require.config.js:

ป้อนคำอธิบายรูปภาพที่นี่


2
อาจเป็นเพราะโซลูชันของคุณสำหรับปัญหา JavaScript คือรหัส C # นอกจากนี้ยังเป็นงานพิเศษและรหัสเพื่อทำสิ่งที่ทำในท้ายที่สุดแบบเดียวกับคำตอบที่ยอมรับ
mAAdhaTTah

@mAAdhaTTah คุณสามารถทำได้ด้วยภาษาฝั่งเซิร์ฟเวอร์ ... ไม่จำเป็นต้องเป็น c # นอกจากนี้ยังเป็นกระบวนการอัตโนมัติการปรับปรุงแคช bust เมื่อคุณสร้างโครงการเวอร์ชันใหม่เพื่อให้แน่ใจว่าลูกค้าจะแคชสคริปต์รุ่นล่าสุดเสมอ ฉันไม่คิดว่าสมควรได้รับเครื่องหมายลบ มันเป็นเพียงการขยายคำตอบโดยนำเสนอวิธีการอัตโนมัติในการแก้ปัญหา
Zach Painter

โดยทั่วไปฉันสร้างสิ่งนี้ขึ้นมาเพราะเมื่อทำการบำรุงรักษาแอปพลิเคชันที่ใช้ require.js ฉันพบว่ามันค่อนข้างน่ารำคาญที่จะต้องคอมเม้นต์ด้วยตนเอง "(ใหม่วันที่ ()). getTime ()) และยกเลิกการใช้ cachebuster คงที่ทุกครั้ง ง่ายต่อการลืมลูกค้าจู่ ๆ ก็ตรวจสอบการเปลี่ยนแปลงและเห็นสคริปต์แคชดังนั้นพวกเขาจึงคิดว่าไม่มีอะไรเปลี่ยนแปลง .. ทั้งหมดเพราะคุณลืมเปลี่ยน cachebuster รหัสพิเศษเล็กน้อยนี้จะลบโอกาสที่จะเกิดขึ้น
Zach Painter

2
ฉันไม่ได้ทำเครื่องหมายลงฉันไม่รู้ว่าเกิดอะไรขึ้นจริง ฉันแค่แนะนำรหัสที่ไม่เพียง แต่ไม่ใช่ js แต่ภาษาเทมเพลต C # จะไม่เป็นประโยชน์สำหรับ JS devs ที่พยายามตอบคำถามของพวกเขา
mAAdhaTTah

-2

ในกรณีของฉันฉันต้องการโหลดแบบฟอร์มเดียวกันทุกครั้งที่ฉันคลิกฉันไม่ต้องการให้การเปลี่ยนแปลงที่ทำกับไฟล์ยังคงอยู่ อาจไม่เกี่ยวข้องกับการโพสต์นี้ แต่อาจเป็นวิธีแก้ปัญหาที่อาจเกิดขึ้นในฝั่งไคลเอ็นต์โดยไม่ต้องตั้งค่าการกำหนดค่าสำหรับความต้องการ แทนที่จะส่งเนื้อหาโดยตรงคุณสามารถทำสำเนาไฟล์ที่ต้องการและเก็บไฟล์จริงไว้

LoadFile(filePath){
    const file = require(filePath);
    const result = angular.copy(file);
    return result;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.