@@ -31,9 +31,7 @@ function createWebpackConfig(outputDirName = '', command, argv = {}) {
3131}
3232
3333function convertToManifestPath ( assetSrc , webpackConfig ) {
34- const manifestData = JSON . parse (
35- fs . readFileSync ( path . join ( webpackConfig . outputPath , 'manifest.json' ) , 'utf8' )
36- ) ;
34+ const manifestData = JSON . parse ( readOutputFileContents ( 'manifest.json' , webpackConfig ) ) ;
3735
3836 if ( typeof manifestData [ assetSrc ] === 'undefined' ) {
3937 throw new Error ( `Path ${ assetSrc } not found in manifest!` ) ;
@@ -42,6 +40,26 @@ function convertToManifestPath(assetSrc, webpackConfig) {
4240 return manifestData [ assetSrc ] ;
4341}
4442
43+ function readOutputFileContents ( filename , config ) {
44+ const fullPath = path . join ( config . outputPath , filename ) ;
45+
46+ if ( ! fs . existsSync ( fullPath ) ) {
47+ throw new Error ( `Output file "${ filename } " does not exist.` ) ;
48+ }
49+
50+ return fs . readFileSync ( fullPath , 'utf8' ) ;
51+ }
52+
53+ function getEntrypointData ( config , entryName ) {
54+ const entrypointsData = JSON . parse ( readOutputFileContents ( 'entrypoints.json' , config ) ) ;
55+
56+ if ( typeof entrypointsData . entrypoints [ entryName ] === 'undefined' ) {
57+ throw new Error ( `The entry ${ entryName } was not found!` ) ;
58+ }
59+
60+ return entrypointsData . entrypoints [ entryName ] ;
61+ }
62+
4563describe ( 'Functional tests using webpack' , function ( ) {
4664 // being functional tests, these can take quite long
4765 this . timeout ( 8000 ) ;
@@ -318,6 +336,22 @@ describe('Functional tests using webpack', function() {
318336 } ) ;
319337 } ) ;
320338
339+ it ( '.mjs files are supported natively' , ( done ) => {
340+ const config = createWebpackConfig ( 'web/build' , 'dev' ) ;
341+ config . addEntry ( 'main' , './js/hello_world' ) ;
342+ config . setPublicPath ( '/build' ) ;
343+
344+ testSetup . runWebpack ( config , ( webpackAssert ) => {
345+ // check that main.js has the correct contents
346+ webpackAssert . assertOutputFileContains (
347+ 'main.js' ,
348+ 'Hello World!'
349+ ) ;
350+
351+ done ( ) ;
352+ } ) ;
353+ } ) ;
354+
321355 describe ( 'addStyleEntry .js files are removed' , ( ) => {
322356 it ( 'Without versioning' , ( done ) => {
323357 const config = createWebpackConfig ( 'web' , 'dev' ) ;
@@ -1628,7 +1662,7 @@ module.exports = {
16281662 } ) ;
16291663 } ) ;
16301664
1631- describe ( 'entrypoints.json' , ( ) => {
1665+ describe ( 'entrypoints.json & splitChunks() ' , ( ) => {
16321666 it ( 'Use "all" splitChunks & look at entrypoints.json' , ( done ) => {
16331667 const config = createWebpackConfig ( 'web/build' , 'dev' ) ;
16341668 config . addEntry ( 'main' , [ './css/roboto_font.css' , './js/no_require' , 'vue' ] ) ;
@@ -1760,18 +1794,18 @@ module.exports = {
17601794 webpackAssert . assertOutputJsonFileMatches ( 'entrypoints.json' , {
17611795 entrypoints : {
17621796 main : {
1763- js : [ '/build/runtime.js' , '/build/vendors~cc515e6e .js' , '/build/default~cc515e6e .js' , '/build/main.js' ] ,
1764- css : [ '/build/default~cc515e6e .css' ]
1797+ js : [ '/build/runtime.js' , '/build/0 .js' , '/build/1 .js' , '/build/main.js' ] ,
1798+ css : [ '/build/1 .css' ]
17651799 } ,
17661800 other : {
1767- js : [ '/build/runtime.js' , '/build/vendors~cc515e6e .js' , '/build/default~cc515e6e .js' , '/build/other.js' ] ,
1768- css : [ '/build/default~cc515e6e .css' ]
1801+ js : [ '/build/runtime.js' , '/build/0 .js' , '/build/1 .js' , '/build/other.js' ] ,
1802+ css : [ '/build/1 .css' ]
17691803 }
17701804 }
17711805 } ) ;
17721806
17731807 // make split chunks are correct in manifest
1774- webpackAssert . assertManifestKeyExists ( 'build/vendors~cc515e6e .js' ) ;
1808+ webpackAssert . assertManifestKeyExists ( 'build/0 .js' ) ;
17751809
17761810 done ( ) ;
17771811 } ) ;
@@ -1809,19 +1843,95 @@ module.exports = {
18091843 } ) ;
18101844 } ) ;
18111845
1812- it ( '.mjs files are supported natively' , ( done ) => {
1813- const config = createWebpackConfig ( 'web/build' , 'dev' ) ;
1814- config . addEntry ( 'main' , './js/hello_world' ) ;
1815- config . setPublicPath ( '/build' ) ;
1846+ it ( 'Make sure chunkIds do not change between builds' , ( done ) => {
1847+ // https://github.com/symfony/webpack-encore/issues/461
1848+ const createSimilarConfig = function ( includeExtraEntry ) {
1849+ const config = createWebpackConfig ( 'web/build' , 'production' ) ;
1850+ config . addEntry ( 'main1' , './js/code_splitting' ) ;
1851+ if ( includeExtraEntry ) {
1852+ config . addEntry ( 'main2' , './js/eslint' ) ;
1853+ }
1854+ config . addEntry ( 'main3' , './js/no_require' ) ;
1855+ config . setPublicPath ( '/build' ) ;
18161856
1817- testSetup . runWebpack ( config , ( webpackAssert ) => {
1818- // check that main.js has the correct contents
1819- webpackAssert . assertOutputFileContains (
1820- 'main.js' ,
1821- 'Hello World!'
1822- ) ;
1857+ return config ;
1858+ } ;
18231859
1824- done ( ) ;
1860+ const configA = createSimilarConfig ( false ) ;
1861+ const configB = createSimilarConfig ( true ) ;
1862+
1863+ testSetup . runWebpack ( configA , ( ) => {
1864+ testSetup . runWebpack ( configB , ( ) => {
1865+ const main3Contents = readOutputFileContents ( 'main3.js' , configA ) ;
1866+ const finalMain3Contents = readOutputFileContents ( 'main3.js' , configB ) ;
1867+
1868+ if ( finalMain3Contents !== main3Contents ) {
1869+ throw new Error ( `Contents after first compile do not match after second compile: \n\n ${ main3Contents } \n\n versus \n\n ${ finalMain3Contents } \n` ) ;
1870+ }
1871+
1872+ done ( ) ;
1873+ } ) ;
1874+ } ) ;
1875+ } ) ;
1876+
1877+ it ( 'Do not change contents or filenames when more modules require the same split contents' , ( done ) => {
1878+ const createSimilarConfig = function ( includeExtraEntry ) {
1879+ const config = createWebpackConfig ( 'web/build' , 'production' ) ;
1880+ config . addEntry ( 'main1' , [ './js/code_splitting' , 'preact' ] ) ;
1881+ config . addEntry ( 'main3' , [ './js/no_require' , 'preact' ] ) ;
1882+ if ( includeExtraEntry ) {
1883+ config . addEntry ( 'main4' , [ './js/eslint' , 'preact' ] ) ;
1884+ }
1885+ config . setPublicPath ( '/build' ) ;
1886+ config . splitEntryChunks ( ) ;
1887+ config . configureSplitChunks ( ( splitChunks ) => {
1888+ // will include preact, but prevent any other splitting
1889+ splitChunks . minSize = 10000 ;
1890+ } ) ;
1891+
1892+ return config ;
1893+ } ;
1894+
1895+ const getSplitVendorJsPath = function ( config ) {
1896+ const entrypointData = getEntrypointData ( config , 'main3' ) ;
1897+
1898+ const splitFiles = entrypointData . js . filter ( filename => {
1899+ return filename !== '/build/runtime.js' && filename !== '/build/main3.js' ;
1900+ } ) ;
1901+
1902+ // sanity check
1903+ if ( splitFiles . length !== 1 ) {
1904+ throw new Error ( `Unexpected number (${ splitFiles . length } ) of split files for main3 entry` ) ;
1905+ }
1906+
1907+ return splitFiles [ 0 ] ;
1908+ } ;
1909+
1910+ const configA = createSimilarConfig ( false ) ;
1911+ const configB = createSimilarConfig ( true ) ;
1912+
1913+ testSetup . runWebpack ( configA , ( ) => {
1914+ testSetup . runWebpack ( configB , ( ) => {
1915+ const vendorPath = getSplitVendorJsPath ( configA ) ;
1916+ const finalVendorPath = getSplitVendorJsPath ( configB ) ;
1917+
1918+ // make sure that the filename of the split vendor file didn't change,
1919+ // even though an additional entry is now sharing its contents
1920+ if ( finalVendorPath !== vendorPath ) {
1921+ throw new Error ( `Vendor filename changed! Before ${ vendorPath } and after ${ finalVendorPath } .` ) ;
1922+ }
1923+
1924+ // make sure that, internally, the split chunk name did not change,
1925+ // which would cause the contents of main3 to suddenly change
1926+ const main3Contents = readOutputFileContents ( 'main3.js' , configA ) ;
1927+ const finalMain3Contents = readOutputFileContents ( 'main3.js' , configB ) ;
1928+
1929+ if ( finalMain3Contents !== main3Contents ) {
1930+ throw new Error ( `Contents after first compile do not match after second compile: \n\n ${ main3Contents } \n\n versus \n\n ${ finalMain3Contents } \n` ) ;
1931+ }
1932+
1933+ done ( ) ;
1934+ } ) ;
18251935 } ) ;
18261936 } ) ;
18271937 } ) ;
0 commit comments